<template>
  <div
    :class="classType"
    :pid="pid"
    :style="absolute ? { position: 'absolute' } : undefined"
    oncontextmenu="return false"
    ondragstart="return false"
    onselectstart="return false"
  >
    <div
      ref="videoComp"
      v-drag
      class="video-dialog normal"
      :class="{
        hide: !isOpen,
        border: all.border,
        'ar-border': all.arBorder,
        checked: all.checked,
        full: classIsFull,
      }"
      :id="'videoDialog' + index"
      v-if="showVideos"
      @dblclick="fullScreen()"
    >
      <div
        v-if="all?.zoom !== false"
        v-drag
        class="tuoZhuai stop-drag"
        :id="'tuoZhuai' + index"
      ></div>
      <div class="video-dialog-bg" :id="'videoPlayBody' + index">
        <VideoCompTool
          ref="videoCompToolRef"
          v-if="quickTool && (!videoAndMap || !ar.type)"
          :deviceCode="deviceCode"
          :channelCode="channelCode"
          :deviceName="deviceName"
          :channelName="channelName"
          :myTransform="myTransform"
          :vueIns="vueIns"
          :division="division"
          :index="index"
          :showQuickTool="showQuickTool"
          :isVideoOpen="isOpen"
          :ar="ar"
          v-on="$listeners"
          @getCompass="getCompass"
          @recordDownload="recordDownload"
        />
        <div class="video-right">
          <i class="extend-1"></i>
          <i class="extend-2"></i>
          <div class="video-real show">
            <div v-if="title && all" class="video-tiitle">
              <i
                class="iconfont icon-luxiangicon1 video-status"
                :class="{
                  'off-line': all.status === '1',
                  'on-pauseing': screenItem.source.src && screenItem.pause,
                  'on-playing': screenItem.source.src && !screenItem.pause,
                }"
              ></i>
              <span class="video-name" :c-tip="channelName" c-tip-auto>{{
                channelName
              }}</span>
              <span v-if="ar.playBack?.length > 1" class="video-time"
                >{{ ar.playBack[0].split(" ")[0] }}至{{
                  ar.playBack[1].split(" ")[0]
                }}</span
              >
            </div>
            <div :id="'videoPlay' + index" class="video-play only1 split-1">
              <div
                class="play-item playing"
                @click="chooseVideo"
                @mousedown="mouseDownVideo"
              >
                <div
                  :id="'videoSingleId' + index"
                  class="choose-style"
                  :class="{
                    'is-screen-full': isScreenFull,
                    'video-and-map-main-video':
                      videoAndMap && videoAndMapMain === 1,
                    'video-and-map-main-map':
                      videoAndMap && videoAndMapMain === 2,
                    'video-and-map-has-quicktool':
                      videoAndMap && quickTool && isScreenFull && !ar.type,
                    'video-and-map-has-quicktool-common':
                      $refs.videoCompToolRef?.commonTool,
                  }"
                >
                  <i
                    v-if="showClose"
                    class="close"
                    @click.stop="removeVideo()"
                    @dblclick.stop
                    c-tip="关闭"
                    c-tip-class="c-tip-normal"
                  />
                  <mapToVideo
                    v-if="videoAndMap"
                    ref="mapToVideoRef"
                    :map-index="index"
                    :longitude="lng"
                    :latitude="lat"
                    :channelCode="channelCode"
                    :deviceCode="deviceCode"
                    :main.sync="videoAndMapMain"
                    :isZoomIn.sync="videoAndMapZoomIn"
                    :layerId="all.layerId"
                    :freckleId="all.freckleId"
                    @mapToVideo="mapToVideo"
                    @out="doVideoAndMap(false)"
                    :vueIns="vueIns"
                  />
                  <videoToMap
                    v-if="videoAndMap"
                    ref="videoToMapRef"
                    :deviceCode="deviceCode"
                    :channelCode="channelCode"
                    :myTransform="myTransform"
                    :vueIns="vueIns"
                    :division="division"
                    :cloudControlSwitch="screenItem.showVideoCloud"
                    :lng="lng"
                    :lat="lat"
                    :main.sync="videoAndMapMain"
                    :isZoomIn.sync="videoAndMapZoomIn"
                    :unCenter="all.unCenter"
                    @cloudControl="cloudControl"
                    @videoToMap="videoToMap"
                    @out="doVideoAndMap(false)"
                  />
                  <Ts ref="ts" />
                  <EasyPlayer
                    v-if="screenItem.source?.src"
                    :ref="screenItem.videoId"
                    :videoUrl="screenItem.source.src"
                    class="video-player"
                    :class="{ large: videoAndMap && videoAndMapZoomIn }"
                    live
                    :easyStretch="easyStretch"
                    :muted="screenItem.muted"
                    :reconnection="true"
                    :playerName="channelName"
                    :has-audio="!!hasAudio || !!compelHasAudio"
                    @recordEnd="recordEnd"
                    @playing="playing"
                    @click.native.stop
                  />
                  <VideoRecordPlayer
                    v-if="recordLook"
                    :deviceCode="deviceCode"
                    :channelCode="channelCode"
                    :channelName="channelName"
                    :record="recordLook"
                  />
                  <Watermark v-if="screenItem.source.src" :vueIns="vueIns" />
                  <div v-if="screenItem.recording === 1" class="record-time">
                    正在录制 {{ parseInt(screenItem.recordTime / 1000) }}S
                  </div>
                  <span v-if="all.hasPlayBackFile === false" class="no-playback"
                    >当前时间段此通道暂无回放视频</span
                  >
                  <div
                    v-if="screenItem.source.src"
                    ref="cloudControl"
                    class="z-bd-cloud"
                    :class="{
                      'full-big big-right-bottom': fullScreenFlag,
                      'cloud-for-videomap': videoAndMap,
                    }"
                    :id="'cloudSingleVideo' + index"
                    v-show="screenItem.showVideoCloud"
                    @click.stop="getControllerInfo"
                    @dblclick.stop
                  >
                    <!-- 云台控制 -->
                    <li
                      @touchstart="platformControl($event, 5, 1)"
                      @touchend="platformControl($event, 5, 0)"
                      @mousedown="platformControl(false, 5, 1)"
                      @mouseup="platformControl(false, 5, 0)"
                    >
                      <div><i class="iconfont icon-sanjiaoxing"></i></div>
                    </li>
                    <li
                      @touchstart="platformControl($event, 1, 1)"
                      @touchend="platformControl($event, 1, 0)"
                      @mousedown="platformControl(false, 1, 1)"
                      @mouseup="platformControl(false, 1, 0)"
                    >
                      <div><i class="iconfont icon-sanjiaoxing"></i></div>
                    </li>
                    <li
                      @touchstart="platformControl($event, 6, 1)"
                      @touchend="platformControl($event, 6, 0)"
                      @mousedown="platformControl(false, 6, 1)"
                      @mouseup="platformControl(false, 6, 0)"
                    >
                      <div><i class="iconfont icon-sanjiaoxing"></i></div>
                    </li>
                    <li
                      @touchstart="platformControl($event, 3, 1)"
                      @touchend="platformControl($event, 3, 0)"
                      @mousedown="platformControl(false, 3, 1)"
                      @mouseup="platformControl(false, 3, 0)"
                    >
                      <div><i class="iconfont icon-sanjiaoxing"></i></div>
                    </li>
                    <li style="visibility: hidden">
                      <i class="iconfont icon-tingzhisaomiao"></i>
                    </li>
                    <li
                      @touchstart="platformControl($event, 4, 1)"
                      @touchend="platformControl($event, 4, 0)"
                      @mousedown="platformControl(false, 4, 1)"
                      @mouseup="platformControl(false, 4, 0)"
                    >
                      <div><i class="iconfont icon-sanjiaoxing"></i></div>
                    </li>
                    <li
                      @touchstart="platformControl($event, 7, 1)"
                      @touchend="platformControl($event, 7, 0)"
                      @mousedown="platformControl(false, 7, 1)"
                      @mouseup="platformControl(false, 7, 0)"
                    >
                      <div><i class="iconfont icon-sanjiaoxing"></i></div>
                    </li>
                    <li
                      @touchstart="platformControl($event, 2, 1)"
                      @touchend="platformControl($event, 2, 0)"
                      @mousedown="platformControl(false, 2, 1)"
                      @mouseup="platformControl(false, 2, 0)"
                    >
                      <div><i class="iconfont icon-sanjiaoxing"></i></div>
                    </li>
                    <li
                      @touchstart="platformControl($event, 8, 1)"
                      @touchend="platformControl($event, 8, 0)"
                      @mousedown="platformControl(false, 8, 1)"
                      @mouseup="platformControl(false, 8, 0)"
                    >
                      <div><i class="iconfont icon-sanjiaoxing"></i></div>
                    </li>
                    <li class="inner-control-rbt">
                      <el-input-number
                        v-model="cameraApertureSpeed"
                        controls-position="right"
                        :min="cameraApertureSpeedMin"
                        :max="cameraApertureSpeedMax"
                        size="mini"
                        @change="cameraApertureSpeedChange"
                        c-tip="步长"
                        c-tip-placement="top"
                        c-tip-class="c-tip-normal"
                      ></el-input-number>
                    </li>
                    <li class="inner-control-bt">
                      <div>
                        <span
                          class="opt-btn opt-left iconfont icon-bianbei-"
                          :class="{ touch: cloudTouch === 12 }"
                          @touchstart="cameraApertureMulChange($event, 12, 1)"
                          @touchend="cameraApertureMulChange($event, 12, 0)"
                          @mousedown="cameraApertureMulChange(false, 12, 1)"
                          @mouseup="cameraApertureMulChange(false, 12, 0)"
                          c-tip="焦距缩小"
                          c-tip-placement="top"
                          c-tip-class="c-tip-normal"
                        >
                        </span>
                      </div>
                      <div>
                        <span
                          class="opt-btn iconfont icon-bianbei"
                          :class="{ touch: cloudTouch === 11 }"
                          @touchstart="cameraApertureMulChange($event, 11, 1)"
                          @touchend="cameraApertureMulChange($event, 11, 0)"
                          @mousedown="cameraApertureMulChange(false, 11, 1)"
                          @mouseup="cameraApertureMulChange(false, 11, 0)"
                          c-tip="焦距放大"
                          c-tip-placement="top"
                          c-tip-class="c-tip-normal"
                        >
                        </span>
                      </div>
                    </li>
                    <div class="cloud-lock">
                      <i
                        v-if="!screenItem.cloudLock && screenItem.optioning"
                        class="iconfont icon-caozuoren optioning"
                        :c-tip="screenItem.optioning"
                        c-tip-placement="top"
                        c-tip-class="c-tip-normal"
                      ></i>
                      <span v-if="screenItem.cloudLock" class="time">{{
                        screenItem.cloudLockTime
                      }}</span>
                      <i
                        class="iconfont lock"
                        :class="
                          screenItem.cloudLock ? 'icon-suoding' : 'icon-jiesuo'
                        "
                        @click.stop="doCloudLock"
                      ></i>
                    </div>
                    <div class="cruise-pause">
                      <span class="cruise-pause-label">巡航</span>
                      <i
                        class="iconfont cruise-pause-icon"
                        :class="
                          screenItem.cruisePause
                            ? 'icon-liebiao-bofang'
                            : 'icon-liebiao-tingzhi'
                        "
                        @click.stop="doCruisePause(screenItem)"
                      ></i>
                      <span
                        v-if="screenItem.cruisePause"
                        class="cruise-pause-time"
                        >{{ screenItem.cruisePauseTime }}</span
                      >
                    </div>
                  </div>
                  <template
                    v-if="
                      screenItem.source?.src && !ar.playBack && !videoAndMap
                    "
                  >
                    <div
                      class="dianzi-cs"
                      v-if="screenItem.source && screenItem.dianzi"
                    >
                      <EasyPlayer
                        :ref="screenItem.videoId + 'dianzi'"
                        :videoUrl="screenItem.source.src"
                        class="video-player"
                        live
                        :easyStretch="easyStretch"
                        :has-audio="false"
                        :reconnection="true"
                        :muted="true"
                      />
                      <div class="point-div"></div>
                    </div>
                    <player-toolbar @resize="playerToolbarResize">
                      <template v-slot:left>
                        <i
                          class="iconfont zoom"
                          :class="
                            screenItem.pause
                              ? 'icon-icon_shipinbofang'
                              : 'icon-icon_shipinzanting'
                          "
                          @click="playOrPause()"
                          :c-tip="screenItem.pause ? '播放' : '暂停'"
                          c-tip-class="c-tip-normal"
                        />
                        <i
                          class="ttext"
                          @click="changeStreamType()"
                          :c-tip="
                            screenItem.source.streamSwitchFlag !== '2' &&
                            screenItem.source.streamType === 2
                              ? '切换主码流'
                              : '切换子码流'
                          "
                          c-tip-class="c-tip-normal"
                          >{{ screenItem.source.streamTypeName }}</i
                        >
                        <el-select
                          class="select c-select"
                          popper-class="c-select-dropdown un-to-body-up"
                          v-model="screenItem.source.protocolType"
                          @change="changeProtocol($event)"
                          :popper-append-to-body="false"
                          c-tip="切换视频流协议类型"
                          c-tip-class="c-tip-normal"
                        >
                          <el-option
                            v-for="pto in protocolTypeOptions"
                            :key="pto.dictValue"
                            :label="pto.dictLabel"
                            :value="pto.dictValue"
                          />
                        </el-select>
                        <i
                          class="iconfont icon-shipinzujian_icon_zhuatu_n"
                          @click="screenshot()"
                          c-tip="抓图"
                          c-tip-class="c-tip-normal"
                        />
                        <i
                          v-if="arloadVideo"
                          class="iconfont"
                          :class="
                            screenItem.recording === 1
                              ? 'icon-icon_jinjiluxiang_s opened'
                              : 'icon-shipinzujian_icon_jinjiluxiang_n'
                          "
                          c-tip="抓视频"
                          c-tip-class="c-tip-normal"
                        />
                        <i
                          v-if="!arloadVideo"
                          class="iconfont"
                          :class="
                            screenItem.recording === 1
                              ? 'icon-icon_jinjiluxiang_s opened'
                              : 'icon-shipinzujian_icon_jinjiluxiang_n'
                          "
                          @click="switchRecording()"
                          c-tip="抓视频"
                          c-tip-class="c-tip-normal"
                        />
                        <i
                          class="iconfont"
                          :class="
                            screenItem.dianzi
                              ? 'icon-shipinzujian_icon_fangda_s opened'
                              : 'icon-shipinzujian_icon_fangda_n'
                          "
                          @click="dianziRate()"
                          c-tip="电子放大"
                          c-tip-class="c-tip-normal"
                        />
                        <i
                          class="iconfont"
                          :class="
                            screenItem.canDraw
                              ? 'icon-shipinzujian_icon_3Dfangda_s opened'
                              : 'icon-shipinzujian_icon_3Dfangda_n'
                          "
                          @click="ready3Dpty()"
                          c-tip="3D放大"
                          c-tip-class="c-tip-normal"
                        />
                        <i
                          class="iconfont"
                          :class="
                            screenItem.focusPoint
                              ? 'icon-shipinzujian_kanzheli_s opened'
                              : 'icon-shipinzujian_kanzheli_n'
                          "
                          @click="readyFocusPoint()"
                          c-tip="看这里"
                          c-tip-class="c-tip-normal"
                        />
                        <i
                          class="iconfont"
                          :class="
                            screenItem.isVoiceIntercom
                              ? 'icon-shipinzujian_icon_yuyinduijiang_s opened'
                              : 'icon-shipinzujian_icon_yuyinduijiang'
                          "
                          @click="voiceIntercom()"
                          :c-tip="
                            screenItem.isVoiceIntercom
                              ? '关闭语音对讲'
                              : '语音对讲'
                          "
                        />
                        <i
                          class="iconfont"
                          :class="
                            screenItem.muted
                              ? 'icon-shipinzujian_icon_shengyin_s opened'
                              : 'icon-shipinzujian_icon_shengyin_n'
                          "
                          @click="easyPlayMute()"
                          c-tip="声音"
                          c-tip-class="c-tip-normal"
                        />
                        <i
                          class="iconfont"
                          :class="
                            screenItem.ptzShow
                              ? 'icon-shipinzujian_icon_PTZ_s opened'
                              : 'icon-shipinzujian_icon_PTZ_n'
                          "
                          @click="ptzClick()"
                          c-tip="PTZ"
                          c-tip-class="c-tip-normal"
                        />
                        <i
                          class="iconfont"
                          :class="
                            screenItem.compass
                              ? 'icon-shipinzujian_icon_zhinanzhen_s opened'
                              : 'icon-shipinzujian_icon_zhinanzhen_n'
                          "
                          @click="getCompass()"
                          c-tip="指北针"
                          c-tip-class="c-tip-normal"
                        />
                        <i
                          class="iconfont"
                          :class="
                            screenItem.showVideoMap
                              ? 'icon-shipinzujian_icon_jingweiduweizhi_s opened'
                              : 'icon-shipinzujian_icon_jingweiduweizhi'
                          "
                          @click="gisControl()"
                          c-tip="查看摄像机地图"
                          c-tip-class="c-tip-normal"
                        />
                        <i
                          class="iconfont"
                          :class="
                            suanfashibieShow
                              ? 'icon-shipinzujian_icon_suanfashibiequyu_s opened'
                              : 'icon-shipinzujian_icon_suanfashibiequyu_n'
                          "
                          @click="selectAlgorithmDistinguish()"
                          c-tip="算法识别区域"
                          c-tip-class="c-tip-normal"
                        />
                        <i
                          class="iconfont"
                          :class="
                            gaojingpingbiShow
                              ? 'icon-shipinzujian_icon_gaojingpingbiquyu_s opened'
                              : 'icon-shipinzujian_icon_gaojingpingbiquyu_n'
                          "
                          @click="selectAlarmShield()"
                          c-tip="告警屏蔽区域"
                          c-tip-class="c-tip-normal"
                        />
                        <i
                          v-if="btnPowers['video_weather_btn'] === '1'"
                          class="iconfont"
                          :class="
                            screenItem.weatherShow
                              ? 'icon-shipinzujian_icon_qixiangshuju_s opened'
                              : 'icon-shipinzujian_icon_qixiangshuju_n'
                          "
                          @click="getWeather()"
                          c-tip="气象数据"
                          c-tip-class="c-tip-normal"
                        />
                        <i
                          v-if="btnPowers['video_air_btn'] === '1'"
                          class="iconfont"
                          :class="
                            screenItem.airShow
                              ? 'icon-shipinzujian_icon_kongqizhiliang_s opened'
                              : 'icon-shipinzujian_icon_kongqizhiliang_n'
                          "
                          @click="getAir()"
                          c-tip="空气质量数据"
                          c-tip-class="c-tip-normal"
                        />
                        <i
                          v-if="isTenant"
                          class="iconfont"
                          :class="
                            screenItem.iotShow
                              ? 'icon-shipinzujian_icon_wulianxinxi_s opened'
                              : 'icon-shipinzujian_icon_wulianxinxi_n'
                          "
                          @click="getMonitorData()"
                          c-tip="监测数据"
                          c-tip-class="c-tip-normal"
                        />
                        <i
                          v-if="isTenant"
                          class="iconfont"
                          :class="
                            grid
                              ? 'icon-shipinzujian_icon_wanggeyuanfenbu_s opened'
                              : 'icon-shipinzujian_icon_wanggeyuanfenbu_n'
                          "
                          @click="getGrid()"
                          c-tip="网格信息"
                          c-tip-class="c-tip-normal"
                        />
                        <i
                          class="iconfont icon-shipinzujian_icon_guanlian_n"
                          @click="gotoRelevantEvents()"
                          c-tip="关联事件"
                          c-tip-class="c-tip-normal"
                        />
                        <i
                          v-if="showQuickTool"
                          class="iconfont"
                          :class="
                            quickTool
                              ? 'icon-shipinzujian_icon_changyonggongnengxianyin_s opened'
                              : 'icon-shipinzujian_icon_changyonggongnengxianyin_n'
                          "
                          @click="quickToolClick()"
                          c-tip="快捷功能"
                          c-tip-class="c-tip-normal"
                        />
                        <i
                          v-if="isTenant"
                          class="iconfont"
                          :class="
                            videoAndMap
                              ? 'icon-shipinzujian_icon_shituliandong_s opened'
                              : 'icon-shipinzujian_icon_shituliandong_n'
                          "
                          @click="doVideoAndMap()"
                          c-tip="视图联动"
                          c-tip-class="c-tip-normal"
                        />
                      </template>
                      <template v-slot:right>
                        <i
                          v-if="isTenant"
                          class="iconfont icon-shipinzujian_icon_gaojingshu"
                          @click="gotoFastWarning()"
                          c-tip="一键告警"
                          c-tip-class="c-tip-normal"
                        />
                        <i
                          v-hasPermi="['video:videoControlRole']"
                          class="iconfont"
                          :class="
                            screenItem.showVideoCloud
                              ? 'icon-shipinzujian_icon_yuntaifangxiang_s opened'
                              : 'icon-shipinzujian_icon_yuntaifangxiang_n'
                          "
                          @click="cloudControl()"
                          c-tip="云台控制"
                          c-tip-class="c-tip-normal"
                        ></i>
                        <i
                          class="iconfont"
                          :class="
                            fullScreenFlag
                              ? 'icon-caozuo-quanping-shousuo1'
                              : 'icon-caozuo-quanping-zhankai4'
                          "
                          @click="fullScreen()"
                          :c-tip="fullScreenFlag ? '退出全屏' : '全屏'"
                          c-tip-class="c-tip-normal"
                        />
                      </template>
                    </player-toolbar>
                    <VideoCompGrid
                      ref="videoCompGridRef"
                      v-if="grid"
                      :lng="lng"
                      :lat="lat"
                      :vueIns="vueIns"
                    />
                    <!--空气质量数据、气象数据、监测数据-->
                    <video-monitor-data
                      :iotShow.sync="screenItem.iotShow"
                      :weatherShow.sync="screenItem.weatherShow"
                      :airShow.sync="screenItem.airShow"
                      :compassShow="screenItem.compass"
                      :videoData="screenItem"
                      :index="index"
                      @iotClose="getMonitorData(false)"
                      @weatherClose="getWeather(false)"
                      @airClose="getAir(false)"
                      @compassClose="getCompass(false)"
                    >
                      <div class="compass-div" v-show="compass">
                        <div class="--left">
                          <img
                            class="b-g"
                            src="~@/assets/image/video/compass_zujian.png"
                          />
                          <div class="map-p">
                            <div class="map-z" :id="'map-z' + index">
                              <div class="map-t" :id="'map-t' + index"></div>
                            </div>
                          </div>
                        </div>
                        <div class="--right">
                          <p>水平角：{{ compass.pan }}°</p>
                          <p>俯仰角：{{ compass.tilt }}°</p>
                          <p>视场角：{{ compass.viewableAngle }}°</p>
                          <p>焦距值：{{ compass.zoom }}</p>
                        </div>
                      </div>
                    </video-monitor-data>
                    <MapForVideo
                      v-if="screenItem.showVideoMap"
                      :ref="'map' + screenItem.videoId"
                      :mapIndex="screenItem.videoId"
                      :longitude="lng"
                      :latitude="lat"
                      :channelCode="channelCode"
                      :deviceCode="deviceCode"
                      v-drag
                      class="no-drag"
                      :scale="myTransform"
                      :vueIns="vueIns"
                      @resize="mapForVideoResize"
                    />
                    <!--算法识别区域下拉框-->
                    <div
                      :id="'suanfashibie-select' + index"
                      class="suanfashibie-select"
                      @dblclick.stop
                    >
                      <div
                        class="suanfashibie-select-box"
                        @click="suanfashibieSelectFunc(index)"
                      >
                        <div class="suanfashibie-text">算法识别区域</div>
                        <div class="suanfashibie-icon">
                          <i
                            :id="'suanfashibie-icon-top' + index"
                            class="icon-class iconfont icon-nav-top"
                          ></i>
                          <i
                            :id="'suanfashibie-icon-bottom' + index"
                            class="icon-class iconfont icon-nav-bottom"
                          ></i>
                        </div>
                      </div>
                      <div
                        :id="'suanfashibie-select-options' + index"
                        class="suanfashibie-select-options"
                      >
                        <div
                          v-for="(itemIndex, i) in suanfashibieOptionsList"
                          :key="i"
                        >
                          <div v-if="itemIndex.list.length > 0">
                            <div
                              v-for="(data, j) in itemIndex.list"
                              :key="j"
                              :class="{ active: data.highlight === 1 }"
                              class="options-box-padding"
                              @click="algorithmHighlight(data, index, j)"
                            >
                              <div class="options-box">
                                <div
                                  class="options-text"
                                  :c-tip="titleSuanFa(data)"
                                  c-tip-class="c-tip-normal"
                                >
                                  {{ data.algorithmName }}{{ "-"
                                  }}{{ data.posType === 1 ? "通道" : "预置位" }}
                                </div>
                                <div class="options-icon">
                                  <i
                                    class="icon-class iconfont icon-shipinzujian_icon_zhuandongdaoyuzhiwei"
                                    :style="
                                      data.active === 1 && data.posType === 2
                                        ? 'display: block'
                                        : 'display: none'
                                    "
                                    c-tip="转动到预置位"
                                    c-tip-class="c-tip-normal"
                                    @click.stop="goPreset(data)"
                                  ></i>
                                  <i
                                    class="icon-class iconfont icon-shipinzujian_icon_biyan"
                                    @click.stop="
                                      algorithmClickClose(data, index, j)
                                    "
                                    :style="
                                      data.active === 1
                                        ? 'display: none'
                                        : 'display: block'
                                    "
                                  ></i>
                                  <i
                                    class="icon-class iconfont icon-shipinzujian_icon_zhengyan"
                                    @click.stop="
                                      algorithmClickOpen(data, index, j)
                                    "
                                    :style="
                                      data.active === 0
                                        ? 'display: none'
                                        : 'display: block'
                                    "
                                  ></i>
                                </div>
                              </div>
                              <div
                                class="options-presetName-class"
                                v-if="data.posType === 2"
                              >
                                {{ data.presetName }}
                              </div>
                              <div
                                class="options-presetName-class"
                                v-if="!isTenant"
                              >
                                {{ data.tenantName }}
                              </div>
                              <div
                                class="options-presetName-class"
                                v-if="!isTenant"
                              >
                                {{ data.tenantId }}
                              </div>
                            </div>
                          </div>
                          <div
                            v-if="itemIndex.list.length === 0 && index === i"
                            class="empty-box"
                          >
                            暂无数据
                          </div>
                        </div>
                      </div>
                    </div>
                    <div
                      :id="'suanfashibie' + index"
                      class="canvas-div"
                      style="pointer-events: none"
                    >
                      <!--                    <div class="canvas" :style="drawForm.videoStyle">-->
                      <!--                      <canvas :id="'suanfashibie-canvas'+index"></canvas>-->
                      <!--                    </div>-->
                      <!--                    <div :id="'suanfashibie-tip'+index" class="tip-class"></div>-->
                      <draw-area
                        v-if="suanfashibieShow"
                        :ref="'suanfashibieDrawArea' + index"
                        :data="drawData"
                      ></draw-area>
                    </div>
                    <!--告警屏蔽区域下拉框-->
                    <div
                      :id="'pingbiquyu-select' + index"
                      class="suanfashibie-select"
                      @dblclick.stop
                    >
                      <div
                        class="suanfashibie-select-box"
                        @click="pingbiquyuSelectFunc(index)"
                      >
                        <div class="suanfashibie-text">告警屏蔽区域</div>
                        <div class="suanfashibie-icon">
                          <i
                            :id="'pingbiquyu-icon-top' + index"
                            class="icon-class iconfont icon-nav-top"
                          ></i>
                          <i
                            :id="'pingbiquyu-icon-bottom' + index"
                            class="icon-class iconfont icon-nav-bottom"
                          ></i>
                        </div>
                      </div>
                      <div
                        :id="'pingbiquyu-select-options' + index"
                        class="suanfashibie-select-options"
                      >
                        <div
                          v-for="(itemIndex, i) in pingbiquyuOptionsList"
                          :key="i"
                        >
                          <div v-if="itemIndex.list.length > 0">
                            <div
                              v-for="(data, j) in itemIndex.list"
                              :key="j"
                              :class="{ active: data.active == 1 }"
                              class="options-box-padding"
                              @click="pingbiquyuClick(data, index, j)"
                            >
                              <div class="options-box">
                                <div
                                  class="options-text"
                                  :c-tip="data.areaName"
                                  c-tip-class="c-tip-normal"
                                >
                                  {{ data.areaName }}
                                </div>
                                <div class="options-icon">
                                  <i
                                    class="icon-class iconfont icon-shipinzujian_icon_zhuandongdaoyuzhiwei"
                                    :style="
                                      data.active == 1
                                        ? 'display: block'
                                        : 'display: none'
                                    "
                                    c-tip="转动到PTZ"
                                    c-tip-class="c-tip-normal"
                                  ></i>
                                  <i
                                    class="icon-class iconfont icon-shipinzujian_icon_biyan"
                                    :style="
                                      data.active == 1
                                        ? 'display: none'
                                        : 'display: block'
                                    "
                                  ></i>
                                  <i
                                    class="icon-class iconfont icon-shipinzujian_icon_zhengyan"
                                    :style="
                                      data.active == 0
                                        ? 'display: none'
                                        : 'display: block'
                                    "
                                  ></i>
                                </div>
                              </div>
                              <div
                                class="options-presetName-class"
                                v-if="!isTenant"
                              >
                                {{ data.tenantName }}
                              </div>
                              <div
                                class="options-presetName-class"
                                v-if="!isTenant"
                              >
                                {{ data.tenantId }}
                              </div>
                            </div>
                          </div>
                          <div
                            v-if="itemIndex.list.length === 0 && index === i"
                            class="empty-box"
                          >
                            暂无数据
                          </div>
                        </div>
                      </div>
                      <div :id="'pingbiquyu' + index" class="canvas-div">
                        <div class="canvas" :style="drawForm.videoStyle">
                          <canvas :id="'pingbiquyu-canvas' + index"></canvas>
                        </div>
                        <div
                          :id="'pingbiquyu-tip' + index"
                          class="tip-class"
                        ></div>
                      </div>
                    </div>
                    <div :id="'divmenu' + index" class="right-menu">
                      <ul>
                        <li
                          class="iconfont icon-shuaxin"
                          @click="reloadVideo()"
                        >
                          &ensp;刷新
                        </li>
                        <li class="iconfont icon-zhuatu" @click="screenshot()">
                          &ensp;抓图
                        </li>
                        <li
                          class="iconfont icon-fangda1"
                          :class="screenItem.dianzi ? 'bgcolorFh' : ''"
                          @click="dianziRate()"
                        >
                          &ensp;电子放大
                        </li>
                        <li
                          class="iconfont icon-a-3Dfangda"
                          :class="screenItem.canDraw ? 'bgcolorFh' : ''"
                          @click="ready3Dpty()"
                        >
                          &ensp;3D放大
                        </li>
                        <li
                          :id="'iconCloud' + screenItem.videoId"
                          class="iconfont icon-yuntai1"
                          :class="screenItem.showVideoCloud ? 'bgcolorFh' : ''"
                          @click="cloudControl()"
                          v-hasPermi="['video:videoControlRole']"
                        >
                          &ensp;云台控制
                        </li>
                        <li
                          :class="
                            screenItem.muted
                              ? 'iconfont icon-jingyin-c'
                              : 'iconfont icon-shengyin-c bgcolorFh'
                          "
                          @click="easyPlayMute($event)"
                        >
                          &ensp;声音
                        </li>
                        <li
                          class="iconfont icon-zhuzimaliuqiehuan"
                          :class="{
                            disfont: screenItem.source.streamSwitchFlag === '2',
                          }"
                          @click="changeStreamType(index)"
                        >
                          &ensp;{{
                            screenItem.source.streamType === 2
                              ? "切换为主码流"
                              : "切换为子码流"
                          }}
                        </li>
                        <li
                          class="iconfont icon-zishiying"
                          :class="easyStretch ? 'bgcolorFh' : ''"
                          @click="adaptBySelf()"
                        >
                          &ensp;自适应
                        </li>
                        <li
                          :class="
                            fullScreenFlag
                              ? 'iconfont icon-caozuo-quanping-shousuo1'
                              : 'iconfont icon-caozuo-quanping-zhankai1'
                          "
                          @click="fullScreen()"
                        >
                          &ensp;{{ fullScreenFlag ? "退出全屏" : "全屏" }}
                        </li>
                        <li
                          v-if="showClose"
                          class="iconfont icon-guanbi"
                          @click="removeVideo()"
                        >
                          &ensp;关闭
                        </li>
                      </ul>
                    </div>
                    <div
                      v-drag
                      class="canvas-div"
                      :style="{
                        display: screenItem.canDraw ? 'block' : 'none',
                      }"
                    >
                      <canvas
                        @mousedown="drawMousedown"
                        @mouseup="drawMouseup"
                        @mousemove="drawMousemove"
                      >
                      </canvas>
                    </div>
                    <div
                      class="focus-div"
                      :style="{
                        display: screenItem.focusPoint ? 'block' : 'none',
                      }"
                      @mousemove="focusMousemove($event)"
                      @click="doFocus($event)"
                    >
                      <div class="focus-big" :id="'focus-big' + index">
                        <span class="iconfont icon-zhongxindian1"></span>
                      </div>
                    </div>
                    <!--PTZ-->
                    <VideoPTZ
                      :ifShow="screenItem.ptzShow"
                      :vueIns="vueIns"
                      :PTZData="screenItem"
                    ></VideoPTZ>
                  </template>
                </div>
              </div>
              <div
                class="fullscreen-bg"
                :class="{ show: fullScreenFlag }"
              ></div>
            </div>
          </div>
          <div
            v-show="screenshotImg"
            class="screen-shot"
            :class="{
              show: screenshotImg && !screenshotKeep,
              keep: screenshotKeep,
              big: screenshotBig,
            }"
          >
            <img :src="screenshotImg" />
            <div class="screen-shot-opt">
              <i
                class="iconfont"
                :class="{
                  'icon-caozuo-quanping-zhankai':
                    screenshotKeep && !screenshotBig,
                  'icon-caozuo-quanping-shousuo': screenshotBig,
                }"
                @click="screenshotOpt(1)"
              ></i>
              <i class="iconfont icon-baocun" @click="screenshotOpt(2)"></i>
              <i class="iconfont icon-shanchu" @click="screenshotOpt(3)"></i>
            </div>
          </div>
        </div>
      </div>
    </div>
    <one-key-alarm
      :show="oneKeyAlarmShow"
      :dafaultPic="oneKeyAlarmDefaultPic"
      :data="oneKeyAlarmDatas"
      :myTransform="myTransform"
      @closed="oneKeyAlarmHide"
      :index="index"
    ></one-key-alarm>
    <video-controller
      v-show="false"
      ref="videoController"
      :screenList="screenList"
      :winChoosed="0"
      :choosedCameraDevice="deviceCode + channelCode"
      :vueIns="vueIns"
      :loginInfo="loginInfo"
    >
    </video-controller>
    <VideoDownloadBox
      :showFlag.sync="recordDownloadShow"
      :videoDownLoadList="recordDownloadDatas"
    />
  </div>
</template>
<script>
/* 引入全局js */
import { $v } from "@/utils/public";
import oneKeyAlarm from "./oneKeyAlarm";
import monitorOnline from "@/assets/image/ar/ipc-online.png";
import monitorOnline_g from "@/assets/image/ar/ipc-online-g.png";
import "videojs-contrib-hls";
import videoController from "./videoController";
import VideoRecordPlayer from "@/views/pages/video/components/videoRecordPlayer.vue";
import PlayerToolbar from "@/views/pages/video/components/playerToolbar.vue";
import {
  doCameraFocusOrZoom,
  doControlPreset,
  doPtzCmds,
  doPtzLocationCmd,
  getAudioChannel,
  getCompass,
  getUserHabit,
  getVideoPlaybackUrl,
  isTenant,
  playBackControl,
  queryAlgorithm,
  queryAreaSuppress,
  queryAreaSuppressList,
  queryVideoDetail,
  setUserHabit,
  thirdLocation,
  turnToPtzByPointAngle,
} from "@/api/video/video";
import {
  pauseResumePatrol,
  queryPauseResumePatrolInfo,
} from "@/api/video/index.js";
import { getVideoRealtimeUrl } from "@/api/video/videoForCB";
import { fabric } from "fabric";
import DrawArea from "@/components/canvas/drawArea";
import { initCTMap } from "@/utils/publicMap";
import Ts from "@/components/canvas/ts.vue";
import { getConfigByKey } from "@/api/system/config";
import VideoCompTool from "@/views/pages/video/videoCompTool.vue";
import VideoCompGrid from "@/views/pages/video/videoCompGrid.vue";
import VideoPTZ from "./videoPTZ";
import Bus from "@/assets/common/bus";
import store from "@/store";
import VideoToMap from "@/views/pages/video/components/videoToMap.vue";
import MapToVideo from "@/views/pages/video/components/mapToVideo.vue";

import {
  addMarker as commAddMarker,
  setZoomAndCenter,
} from "@/utils/openLayerCommon";
import VideoRecords from "@/views/pages/video/components/videoRecords.vue";
import VideoDownloadBox from "@/views/pages/video/components/video-download/videoDownloadBox.vue";
import VideoMonitorData from "@/views/pages/video/videoMonitorData.vue";
import MapForVideo from "@/views/pages/video/components/MapForVideo.vue";
import $ from "jquery";
import { Recorder } from "@/components/audio/recorder";

const defaultForm = {
  positions: [],
};

const defaultDrawForm = {
  id: "",
  posType: "",
  presetId: null,
  algorithmCode: "",
  videoStyle: "",
  drawing: false,
  videoUrl: "",
  width: 0,
  height: 0,
  areas: [],
  preset: { presetId: "" },
};

const defaultFabricObject = {
  roof: null,
  roofPoints: [],
  lines: [],
  lineCounter: 0,
  drawingObject: {},
  fabricObj: null,
  mouseFrom: {},
  canvas: null,
  Point: {},
  power: [], //按钮权限列表
};
const defaultArea = [
  {
    monitorAreaId: "1",
    moniPointList: [
      { monitorPointId: 1, percentX: 0.001, percentY: 0.001 },
      { monitorPointId: 2, percentX: 0.001, percentY: 0.999 },
      { monitorPointId: 3, percentX: 0.999, percentY: 0.999 },
      { monitorPointId: 4, percentX: 0.999, percentY: 0.001 },
      { monitorPointId: 5, percentX: 0.001, percentY: 0.001 },
    ],
  },
];
export default {
  name: "video-real-comp",
  components: {
    MapForVideo,
    VideoMonitorData,
    VideoDownloadBox,
    VideoRecords,
    MapToVideo,
    VideoToMap,
    VideoPTZ,
    oneKeyAlarm,
    DrawArea,
    videoController,
    Ts,
    VideoCompTool,
    VideoCompGrid,
    VideoRecordPlayer,
    PlayerToolbar,
  },
  props: {
    showVideo: {
      //是否显示
      type: Boolean,
      default: true,
    },
    deviceCode: {
      //设备编码
      type: String,
    },
    channelCode: {
      //通道编码
      type: String,
    },
    longitude: {
      //经度
      type: [String, Number],
    },
    latitude: {
      //纬度
      type: [String, Number],
    },
    positonLeft: {
      //距离左方距离
      type: [String, Number],
    },
    positonTop: {
      //距离上方距离
      type: [String, Number],
    },
    videoWidth: {
      //视频宽度
      type: [String, Number],
    },
    videoHeight: {
      //视频高度
      type: [String, Number],
    },
    showClose: {
      //展现关闭按钮
      type: Boolean,
      default: true,
    },
    transform: {
      //缩放参数
      type: [String, Number],
    },
    transformOrigin: {
      //缩放点
      type: String,
    },
    index: {
      //序号
      type: Number,
    },
    suffix: {
      //后缀，防止id重复
      type: String,
      default: "",
    },
    lookHere: {}, //看这里
    all: {
      type: Object,
      default: () => {
        return {};
      },
    }, //所有参数
    division: {
      // 判断分屏视频定位是否启用,或设置视频联动初始定位
      type: String,
      default: "0",
    },
    vueIns: {
      // 分屏传入this
      type: Object,
      default: () => {
        return {};
      },
    },
    total: {
      // 分屏数量
      type: Number,
    },
    dragVideo: {
      // 判断是否可以拖动视屏
      type: Boolean,
      default: false,
    },
    showQuickTool: {
      // 判断快捷方式是否显示
      type: Boolean,
      default: true,
    },
    easyStretchVideo: {
      // 判断视频自适应
      type: Boolean,
      default: true,
    },
    ar: {
      //ar大屏定制
      type: Object,
      default: () => {
        return {};
      },
    },
    isOpen: {
      //是否打开播放器
      type: Boolean,
      default: true,
    },
    title: {
      //是否有标题头
      type: Boolean,
      default: false,
    },
    iframId: {
      //iframId
      type: String,
      default: "",
    },
    neoPosition: Object,
    absolute: Boolean, // 是否使用绝对定位
    defaultQuickTool: Boolean, // 是否默认打开快捷功能，有些地方有需要默认打开快捷功能的需求
  },
  data() {
    return {
      deviceName: "",
      channelName: "",
      videoAndMapZoomIn: false, //视图联动辅窗放大缩小
      isScreenFull: false, //是否全屏
      videoAndMapMain: 1, //视图联动主屏, 1: 视频, 2: 地图
      isGt: false,
      pid: this.getUUID(), //组件唯一id
      grid: false, //网格信息
      quickTool: false, //快捷功能开关
      videoAndMap: false, //视图联动
      videoAndMapBig: 1, //视频联动放大模块, 1: 视频, 2: 地图
      algorithmChooseList: [],
      suanfashibieShow: false,
      gaojingpingbiShow: false,
      drawData: {
        deviceCode: "", //设备编码(必传)
        channelCode: "", //通道编码(必传)
        draw: [],
      },
      classType: false, //行业样式
      that: this,
      maxWidth: 760,
      minWidth: 380,
      minHeight: (380 * 9) / 16,
      weatherAirHeight: 368,
      myTransform: 1,
      loginInfo: {}, //登录信息
      oneKeyAlarmShow: false, //一键告警弹出框
      oneKeyAlarmDefaultPic: false,
      oneKeyAlarmDatas: false, //一键告警入参数据
      screenshotImg: "", //快照
      screenshotKeep: false, //快照 保持小窗口
      screenshotBig: false, //快照 大图
      screenshotAutoClose: false, //快照 自动关闭
      fullScreenFlag: false, //是否全屏
      fullScreenStatus: false, //是否全屏
      cloudTouch: false, //触屏点击控制台样式
      protocolTypeOptions: [], //流协议类型列表
      easyStretch: true, //播放窗口自适应
      cameraApertureSpeed: 5, //摄像机 速度
      iframeOffsetLeft: 0, // iframe左侧距离
      iframeOffsetTop: 0, // iframe上侧距离
      iframeOffsetWidth: 0, // iframe宽度
      iframeOffsetHeight: 0, // iframe高度
      weatherRight: false, // 气象数据右侧展示
      isTenant: false, // 是否为租户用户
      screenList: [],
      screenItem: {
        source: false,
        pause: false,
        canDraw: false,
        muted: true,
        weatherShow: false,
        focusPoint: false,
        compass: false,
        airShow: false,
        iotShow: false,
        showVideoMap: false,
        showVideoCloud: false,
        dianzi: false,
        rateNum: 1,
        oldLeft: 0,
        oldTop: 0,
        moveFlag: false,
        downX: 0,
        downY: 0,
        moveXoffset: 0,
        moveYoffset: 0,
        suanFaShiBie: false,
        pingBiQuYu: false,
        pingBiQuYuArry: false,
        ptzShow: false,
      },
      defaultScreenItem: {
        source: {
          streamType: "",
          streamTypeName: "",
          streamSwitchFlag: "",
          src: "",
          protocolType: "",
        },
        pause: false,
        muted: true,
        weatherShow: false,
        focusPoint: false,
        compass: false,
        airShow: false,
        iotShow: false,
        canDraw: false,
        showVideoMap: false,
        showVideoCloud: false,
        dianzi: false,
        rateNum: 1,
        oldLeft: 0,
        oldTop: 0,
        moveFlag: false,
        downX: 0,
        downY: 0,
        moveXoffset: 0,
        moveYoffset: 0,
      },
      drawX: 0,
      drawY: 0,
      drawXoffset: 0,
      drawYoffset: 0,
      drawArea: false,
      cameraApertureSpeedMin: 1, //摄像机 速度 最小值
      cameraApertureSpeedMax: 8, //摄像机 速度 最大值
      compass: {
        pan: 0,
        tilt: 0,
        zoom: 0,
        viewableAngle: 0,
      },
      fabricObject: JSON.parse(JSON.stringify(defaultFabricObject)),
      algoForm: JSON.parse(JSON.stringify(defaultForm)),
      drawForm: JSON.parse(JSON.stringify(defaultDrawForm)),
      suanfashibieOptionsList: [],
      pingbiquyuOptionsList: [],
      leftTipCoordinate: "50%",
      topTipCoordinate: "50%",
      style: "",

      map: null,
      mapMap: null, //地图
      removeEndPoint: null,
      mapInstance: null, //地图
      centers: [116.396908, 39.908607], //高德地图默认中心点
      mapSearchOption: {
        city: "全国",
        citylimit: true,
      },
      placeSearch: null,
      btnPowers: {}, //按钮权限
      dragMaxWidth: 1490, //放大最大宽度
      dragMaxHeight: 839, //放大最大高度
      dragMinWidth: 380, //缩小最小宽度
      dragMinHeight: 214, //缩小最小高度
      commonToolMinWidth: 932, //可使用常用功能的最小宽度
      commonToolMinHeight: 525, //可使用常用功能的最小高度
      lng: "",
      lat: "",
      showVideos: true,
      permissions: "",
      recordDownloadShow: 0, //录像下载显示
      recordDownloadDatas: [], //录像下载数据
      recordLook: false, //查看录像
      classIsFull: false,
      arloadVideo: false, //是否是ar大屏的录制视频
      compelHasAudio: false,
      speed: 0,
    };
  },
  watch: {
    longitude: {
      handler(lng) {
        this.lng = lng;
      },
      immediate: true,
    },
    latitude: {
      handler(lat) {
        this.lat = lat;
      },
      immediate: true,
    },
    positonLeft: {
      handler() {
        this.videoCalc();
      },
      immediate: true,
    },
    videoHeight() {
      this.videoCalc();
    },
    videoWidth() {
      this.videoCalc();
    },
    positonTop: {
      handler() {
        this.videoCalc();
      },
      immediate: true,
    },
    channelCode() {
      this.replacePlay();
    },
    //监听双击-电子围栏放大缩小
    fullScreenFlag() {
      // console.log('========================', this.fullScreenFlag)
      setTimeout(() => {
        if (
          this.screenItem.suanFaShiBie === false &&
          this.screenItem.pingBiQuYu !== false
        ) {
          this.pingbiquyuDbClick();
        }
        if (
          this.screenItem.suanFaShiBie !== false &&
          this.screenItem.pingBiQuYu === false
        ) {
          this.suanfashibieDbClick();
        }
      }, 200);
    },
    showVideo: {
      // 监听视屏关闭
      handler: function () {
        this.showVideos = this.showVideo;
      },
      immediate: true,
    },
    easyStretchVideo: {
      handler: function (val) {
        this.easyStretch = val;
      },
      immediate: true,
    },
  },
  computed: {
    /**
     * 是否开启flv音频
     */
    hasAudio() {
      return (
        this.$store.getters.flvHasAudio ||
        !this.screenItem.source?.src?.includes(".flv")
      );
    },
  },
  created() {
    window.$ = $;
    this.isTenant = isTenant();
    if (Object.keys(this.vueIns).length) {
      this.$store = this.vueIns.$store;
    }
    this.loginInfo = this.$store.getters.userInfo;
    this.permissions = this.$store.getters.permissions;
    this.screenItem.canDraw = this.defaultScreenItem.canDraw =
      this.$store.getters.videoPlayer3dSetting === 0;
    this.initDicts();
    const chooseTradeId = this.loginInfo.chooseTradeId;
    try {
      if (chooseTradeId === "100000") {
        import("@/assets/styles/video-linye.scss");
        this.classType = "ly";
      } else {
        this.classType = "ty";
      }
    } catch (error) {
      $message.e("引入行业对应样式失败！");
      return false;
    }
  },
  beforeDestroy() {
    window.removeEventListener("resize", this.windowResize);
    if (this.resizeObserver) {
      this.resizeObserver.disconnect();
    }
    clearTimeout(this.resizeTiming);
    this.closeVoiceIntercom();
  },
  mounted() {
    this.initPlay();
    this.getInitViewBox(); //初始化拖拽范围
    window.addEventListener("resize", this.windowResize);
    this.resizeObserver = new ResizeObserver(() => {
      const w = $("#videoDialog" + this.index).outerWidth();
      const h = $("#videoDialog" + this.index).outerHeight();
      this.weatherRight = h < this.weatherAirHeight;
      if (
        !this.all.compelScale &&
        this.myTransform !== 1 &&
        w * this.myTransform > this.minWidth
      ) {
        $("#videoDialog" + this.index).css({
          transform: "none",
          width: w * this.myTransform,
          height: h * this.myTransform,
        });
        this.myTransform = 1;
      }
      clearTimeout(this.resizeTiming);
      this.resizeTiming = setTimeout(() => {
        this.checkScreenFull();
      }, 200);
    });
    this.checkScreenFull();
    this.$nextTick(() => {
      this.videoCalc();
      this.resizeObserver.observe($("#videoPlayBody" + this.index)[0]);

      // 初始化时如果传入了额外的定定位数据，那么使用这个数据移动一下当前位置
      if (this.neoPosition) {
        this.moveSimple(this.neoPosition);
      }
    });
    const classTypes = this.$store.getters.industry.split(" ");
    if (classTypes.includes("g")) {
      //国土
      this.isGt = true;
    } else {
      this.isGt = false;
    }
  },
  activated() {
    this.videoGotoPlay(1);
  },
  deactivated() {
    this.videoGotoPlay(0);
  },
  directives: {
    drag: {
      // 指令的定义
      bind: function (el, binding, vNode) {
        const _this = vNode.context;
        /* 拖动 */
        // let self = this // 上下文
        el.onmousedown = (e) => {
          if (_this.isScreenFull) {
            return false;
          }
          // 处理分屏视频层级问题
          if (_this.total !== 0) {
            for (let i = 0; i < _this.total; i++) {
              if (_this.$props.index === i) {
                $("#videoDialog" + i).css("z-index", 101);
              } else {
                $("#videoDialog" + i).css("z-index", 100);
              }
            }
          }

          if (_this.dragVideo === true) {
            return;
          }

          let iframDiv = document.getElementById(_this.iframId);
          if (iframDiv) {
            console.log("按下");
            iframDiv.style.pointerEvents = "none";
          }

          e.stopPropagation();
          if (el._prevClass.indexOf("no-drag") !== -1) {
            return false;
          }
          $(el).parents(".video-dialog-drag").css({
            width: "100%",
            height: "100%",
          });
          $(el)
            .parents(".video-item-body, .video-item-body-c")
            .find(".video-item")
            .removeClass("on");
          $(el).parents(".video-item").addClass("on");
          if (el._prevClass.indexOf("stop-drag") === -1) {
            const computedStyle = document.defaultView.getComputedStyle(
              el,
              null
            );
            let event = e || window.event;
            // 当前鼠标坐标
            const currentX = event.clientX;
            const currentY = event.clientY;
            let computedStyleLeft, computedStyleTop;
            // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
            if (computedStyle.left.includes("%")) {
              computedStyleLeft =
                +document.body.clientWidth *
                (+computedStyle.left.replace(/\%/g, "") / 100);
              computedStyleTop =
                +document.body.clientHeight *
                (+computedStyle.top.replace(/\%/g, "") / 100);
            } else {
              computedStyleLeft = +computedStyle.left.replace(/\px/g, "");
              computedStyleTop = +computedStyle.top.replace(/\px/g, "");
            }
            document.onmousemove = function (mousemoveEvent) {
              if (
                el._prevClass.indexOf("z-bd") > -1 ||
                el._prevClass.indexOf("canvas-div") > -1 ||
                _this.all?.drag === false
              ) {
                return false;
              }
              const dialogElementLeft =
                mousemoveEvent.clientX - currentX + computedStyleLeft;
              const dialogElementTop =
                mousemoveEvent.clientY - currentY + computedStyleTop;
              el.style.left = dialogElementLeft + "px";
              el.style.top = dialogElementTop + "px";
              _this.resize();
              //通知工具组件移动位置
              _this.$refs.videoCompToolRef?.moveVideoBoxPosition();
              //通知视图联动移动位置
              _this.$refs.videoToMapRef?.moveVideoBoxPosition();
            };
            document.onmouseup = () => {
              if (iframDiv) {
                iframDiv.style.pointerEvents = "auto";
              }
              document.onmousemove = null;
              document.onmouseup = null;
              $(el).parents(".video-dialog-drag").removeAttr("style");
            };
          } else {
            //缩放
            const $parent = $(el).parent();
            document.onmousemove = function (mousemoveEvent) {
              //解决onmouseup事件有时候不触发
              if (el.stopPropagation) {
                el.stopPropagation();
              }
              if (el.preventDefault) {
                el.preventDefault();
              }
              const computedStyle = document.defaultView.getComputedStyle(
                el.parentNode,
                null
              );
              // 当前鼠标坐标
              let computedStyleLeft, computedStyleTop, width, height;
              // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
              if (computedStyle.left.includes("%")) {
                computedStyleLeft =
                  +document.body.clientWidth *
                  (+computedStyle.left.replace(/\%/g, "") / 100);
                computedStyleTop =
                  +document.body.clientHeight *
                  (+computedStyle.top.replace(/\%/g, "") / 100);
                width = el.parentNode.style.width.replace(/\%/g, "") / 100;
                height = el.parentNode.style.height.replace(/\%/g, "") / 100;
              } else {
                computedStyleLeft = +computedStyle.left.replace(/\px/g, "");
                computedStyleTop = +computedStyle.top.replace(/\px/g, "");
                width = el.parentNode.style.width.replace(/\px/g, "");
                height = el.parentNode.style.height.replace(/\px/g, "");
              }
              $parent.addClass("moving");
              let transform = _this.myTransform;

              const dialogElementWidth =
                (mousemoveEvent.clientX - computedStyleLeft) /
                Number(transform);
              let scale =
                (mousemoveEvent.clientX - computedStyleLeft) /
                Number(transform) /
                width;
              let dialogElementHeight = height * scale;

              //打开常用功能时，禁止拖拽到小于932px*525px尺寸
              if (
                _this.$refs.videoCompToolRef &&
                _this.$refs.videoCompToolRef.commonTool
              ) {
                //打开常用功能
                if (dialogElementWidth <= _this.commonToolMinWidth) {
                  return;
                }
                if (dialogElementHeight <= _this.commonToolMinHeight) {
                  return;
                }
              }
              //放大缩小处理（添加限制范围）
              let vw = 0;
              let vh = 0;

              if (dialogElementWidth >= _this.dragMaxWidth) {
                vw = _this.dragMaxWidth;
              } else if (dialogElementWidth <= _this.dragMinWidth) {
                vw = _this.dragMinWidth;
              } else {
                vw = dialogElementWidth;
              }
              if (dialogElementHeight >= _this.dragMaxHeight) {
                vh = _this.dragMaxHeight;
              } else if (dialogElementHeight <= _this.dragMinHeight) {
                vh = _this.dragMinHeight;
              } else {
                vh = dialogElementHeight;
              }
              el.parentNode.style.width = vw + "px";
              el.parentNode.style.height = vh + "px";

              _this.resize();
            };
            document.onmouseup = () => {
              if (iframDiv) {
                iframDiv.style.pointerEvents = "auto";
              }
              $parent.removeClass("moving");
              document.onmousemove = null;
              document.onmouseup = null;
              $(el).parents(".video-dialog-drag").removeAttr("style");
            };
          }
          _this.setTopZindex();
        };
        el.ontouchstart = (e) => {
          $(el).parents(".video-dialog-drag").css({
            width: "100%",
            height: "100%",
          });
          e.stopPropagation();
          let event = e || window.event;
          // 当前鼠标坐标
          const currentX = event.changedTouches[0].clientX;
          const currentY = event.changedTouches[0].clientY;
          let computedStyleLeft, computedStyleTop;
          // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
          if (computedStyle.left.includes("%")) {
            computedStyleLeft =
              +document.body.clientWidth *
              (+computedStyle.left.replace(/\%/g, "") / 100);
            computedStyleTop =
              +document.body.clientHeight *
              (+computedStyle.top.replace(/\%/g, "") / 100);
          } else {
            computedStyleLeft = +computedStyle.left.replace(/\px/g, "");
            computedStyleTop = +computedStyle.top.replace(/\px/g, "");
          }
          document.ontouchmove = function (touchmoveEvent) {
            if (
              el._prevClass.indexOf("z-bd") > -1 ||
              el._prevClass.indexOf("canvas-div") > -1 ||
              _this.all?.drag === false
            ) {
              return false;
            }
            const dialogElementLeft =
              touchmoveEvent.changedTouches[0].clientX -
              currentX +
              computedStyleLeft;
            const dialogElementTop =
              touchmoveEvent.changedTouches[0].clientY -
              currentY +
              computedStyleTop;
            el.style.left = dialogElementLeft + "px";
            el.style.top = dialogElementTop + "px";
            _this.$refs.videoCompToolRef?.moveVideoBoxPosition();
          };
          document.ontouchend = (e) => {
            document.ontouchmove = null;
            document.ontouchend = null;
            $(el).parents(".video-dialog-drag").removeAttr("style");
          };
          _this.setTopZindex();
        };
      },
    },
  },
  methods: {
    /**
     * 录像回放倍速播放
     */
    playbackControl(speed) {
      this.speed = speed;
      const params = {
        deviceCode: this.deviceCode,
        channelCode: this.channelCode,
        streamControlId: this.streamControlId,
        controlType: 3, //1暂停, 2播放, 3倍速
        speed,
        storageType: 1, //0: 前端录像, 1: 中心存储
      };
      playBackControl(params).then((resp) => {
        if (resp.code !== 200) {
          $message.a(resp);
        }
      });
    },
    /**
     * 播放成功回调
     */
    playing(isH265) {
      console.log("::isH265::", isH265);
      this.isPlaying = true;
      if (this.all.hasAudio || this.mutedFlag === false) {
        this.easyPlayMute(false);
        delete this.mutedFlag;
        delete this.all.hasAudio;
      }
    },
    /**
     * 自动打开功能
     */
    async autoOpenTool() {
      if (this.ar.playBack) {
        return false;
      }
      delete this.isPlaying;
      this.getMemory().then((memory) => {
        this.memory = memory;
        memory.forEach((fn) => {
          let flag = true;
          if (fn === "easyPlayMute") {
            if (!this.isPlaying) {
              this.mutedFlag = false;
              return false;
            }
            flag = false;
          }
          this[fn](flag);
        });
      });
    },
    /**
     * 打开功能
     */
    openTool(key, flag) {
      try {
        const fns = {
          getCompass: [
            "ptzClick",
            "selectAlgorithmDistinguish",
            "selectAlarmShield",
            "getGrid",
            "gisControl",
          ], //指北针
          getWeather: [
            "ptzClick",
            "selectAlgorithmDistinguish",
            "selectAlarmShield",
            "getGrid",
            "gisControl",
          ], //气象数据
          getAir: [
            "ptzClick",
            "selectAlgorithmDistinguish",
            "selectAlarmShield",
            "getGrid",
            "gisControl",
          ], //空气质量指数
          getMonitorData: [
            "ptzClick",
            "selectAlgorithmDistinguish",
            "selectAlarmShield",
            "getGrid",
            "gisControl",
          ], //监测数据
          ptzClick: [
            "getCompass",
            "getWeather",
            "getAir",
            "getMonitorData",
            "selectAlgorithmDistinguish",
            "selectAlarmShield",
          ], //ptz
          selectAlgorithmDistinguish: [
            "getCompass",
            "getWeather",
            "getAir",
            "getMonitorData",
            "ptzClick",
            "selectAlarmShield",
          ], //算法识别区域
          selectAlarmShield: [
            "getCompass",
            "getWeather",
            "getAir",
            "getMonitorData",
            "ptzClick",
            "selectAlgorithmDistinguish",
          ], //告警屏蔽区域
          getGrid: [
            "getCompass",
            "getWeather",
            "getAir",
            "getMonitorData",
            "gisControl",
          ], //网格信息
          gisControl: [
            "getCompass",
            "getWeather",
            "getAir",
            "getMonitorData",
            "getGrid",
          ], //查看摄像机地图
          dianziRate: [], //电子放大
          ready3Dpty: [], //3D放大
          readyFocusPoint: [], //看这里
          cloudControl: [], //云台控制
          easyPlayMute: [], //声音
          doVideoAndMap: [
            "getCompass",
            "getWeather",
            "getAir",
            "getMonitorData",
            "ptzClick",
            "selectAlgorithmDistinguish",
            "selectAlarmShield",
            "getGrid",
            "gisControl",
            "dianziRate",
            "ready3Dpty",
            "readyFocusPoint",
            "cloudControl",
          ], //视图联动
          close: [
            "switchRecording",
            "dianziRate",
            "ready3Dpty",
            "readyFocusPoint",
            "voiceIntercom",
            "ptzClick",
            "getCompass",
            "gisControl",
            "selectAlgorithmDistinguish",
            "selectAlarmShield",
            "getWeather",
            "getAir",
            "getMonitorData",
            "getGrid",
            "doVideoAndMap",
            "cloudControl",
          ], //关闭所有
        };
        if (flag && fns[key]?.length) {
          fns[key].forEach((fn) => {
            this[fn](false);
          });
        }
        if (key !== "close") {
          this.setMemory(key, flag);
        }
      } catch (e) {
        console.error(e);
      }
    },
    /**
     * 设置底部菜单记忆
     */
    async setMemory(key, flag) {
      const { deviceCode, channelCode } = this;
      if (!deviceCode || !channelCode) {
        return false;
      }
      const habitKey = "player_" + deviceCode + "_" + channelCode;
      const memory = this.memory || [];
      const index = memory.findIndex((item) => item === key);
      if (key === "doVideoAndMap" && (flag || index < 0)) {
        return false;
      }
      if (key === "easyPlayMute") {
        flag = !flag;
      }
      if (flag && index < 0) {
        memory.push(key);
      }
      if (!flag && index > -1) {
        memory.splice(index, 1);
      }
      clearTimeout(this.setMemoryTiming);
      this.setMemoryTiming = setTimeout(() => {
        setUserHabit({ habitKey, habitValue: JSON.stringify(memory) });
      }, 500);
    },
    /**
     * 获取底部菜单记忆
     */
    getMemory() {
      return new Promise((resolve, reject) => {
        const { deviceCode, channelCode } = this;
        if (!deviceCode || !channelCode) {
          reject();
          return false;
        }
        const habitKey = "player_" + deviceCode + "_" + channelCode;
        getUserHabit({ habitKey })
          .then((resp) => {
            let memory = [];
            if (resp.code === 200 && resp.data) {
              memory = JSON.parse(resp.data);
            }
            resolve(memory);
          })
          .catch(() => {
            reject();
          });
      });
    },
    /**
     * 播放窗口底部菜单高度变化回调
     */
    playerToolbarResize(height) {
      this.$el.style.setProperty("--player-toolbar-height", height);
    },
    /**
     * 播放窗口摄像机定位高度变化回调
     */
    mapForVideoResize(height) {
      this.$el.style.setProperty("--map-for-video-height", height);
      this.fitCloudAndMap(2);
    },
    /**
     * 录像下载
     */
    recordDownload({ show, datas = [], recordLook }) {
      if (recordLook !== undefined) {
        this.recordLook = recordLook;
        console.log("=========================", recordLook);
        return false;
      }
      if (datas?.[0]?.storageType === 0) {
        $message.w("暂不支持前端录像下载");
        return false;
      }
      this.recordDownloadShow = 0;
      this.recordDownloadDatas = datas;
      this.$nextTick(() => {
        this.recordDownloadShow = show;
      });
    },
    /**
     * 移动
     */
    move(e) {
      this.videoCalc(e.videoWidth, e.videoHeight, e.positonLeft, e.positonTop);
      this.resize();
      //通知工具组件移动位置
      this.$refs.videoCompToolRef?.moveVideoBoxPosition();
      //通知视图联动移动位置
      this.$refs.videoToMapRef?.moveVideoBoxPosition();
    },
    /**
     * 定位 ar组件定制
     */
    positionForAr(e) {
      e.positonTop += $(".page-view:visible").offset()?.top || 0;
      this.videoCalc(e.videoWidth, e.videoHeight, e.positonLeft, e.positonTop);
      //通知工具组件移动位置
      this.$refs.videoCompToolRef?.moveVideoBoxPosition();
      //通知视图联动移动位置
      this.$refs.videoToMapRef?.moveVideoBoxPosition();
    },
    /**
     * 移动 ar组件定制
     */
    moveForAr(e = {}) {
      const { width = 0, height = 0, left = 0, top = 0 } = e;
      const { offsetWidth, offsetHeight, offsetLeft, offsetTop } =
        this.$refs.videoComp;
      this.videoCalc(
        offsetWidth + width,
        offsetHeight + height,
        offsetLeft + left,
        offsetTop + top
      );
      //通知工具组件移动位置
      this.$refs.videoCompToolRef?.moveVideoBoxPosition();
      //通知视图联动移动位置
      this.$refs.videoToMapRef?.moveVideoBoxPosition();
    },
    /**
     * 最小化 ar组件定制
     */
    toMinimize(status) {
      this.$refs.videoCompToolRef?.toMinimize(status);
    },
    // 极度简化的移动方法，仅仅移动窗口位置，不触发其他操作
    moveSimple(e) {
      const { videoWidth, videoHeight, positonLeft, positonTop } = e;
      const width = videoWidth;
      const height = videoHeight;
      const left = positonLeft;
      const top = positonTop;
      let myStyle = {
        width: width + "px",
        height: height + "px",
        left: left + "px",
        top: top + "px",
      };
      this.resize();
      if (this.myTransform !== 1) {
        myStyle.transform = "scale(" + this.myTransform + ")";
      }
      if (this.transformOrigin) {
        myStyle["transform-origin"] = this.transformOrigin;
      }
      this.style = myStyle;
      this.toFitAr();
      $("[pid=" + this.pid + "] .video-dialog").css(this.style);
      return myStyle;
    },
    /**
     * 视频传递参数到地图
     */
    videoToMap(params) {
      this.$refs.mapToVideoRef?.videoToMap(params);
    },
    /**
     * 地图传递参数到视频
     */
    mapToVideo(params) {
      this.$refs.videoToMapRef?.mapToVideo(params);
    },
    /**
     * 大小位置改变回调
     */
    resize() {
      if (this.isScreenFull) {
        return false;
      }
      const { offsetLeft, offsetTop, offsetWidth, offsetHeight } =
        this.$refs.videoComp;
      this.$emit("update:positonLeft", offsetLeft);
      this.$emit("update:positonTop", offsetTop);
      this.$emit("update:videoWidth", offsetWidth);
      this.$emit("update:videoHeight", offsetHeight);
    },
    /**
     * 初始化播放
     */
    initPlay(replace) {
      this.screenItem.sources = [
        {
          camera: {
            deviceCode: this.deviceCode,
            channelCode: this.channelCode,
            longitude: this.lng,
            latitude: this.lat,
          },
        },
      ];
      this.screenList = [this.screenItem];
      this.getCameraDetail();
      this.doHabitPlayVideo();
      if (replace) {
        return false;
      }
      this.quickTool = !!this.defaultQuickTool;
      if (
        this.showQuickTool &&
        (this.ar.type === 1 || this.all.openQuickTool)
      ) {
        this.quickTool = true;
      }
    },
    /**
     * 更换设备播放
     */
    replacePlay() {
      clearTimeout(this.replacePlayTiming);
      this.replacePlayTiming = setTimeout(() => {
        this.openTool("close", true);
        if (this.screenItem.source?.src) {
          this.screenItem.source.src = "";
        }
        this.initPlay(true);
      }, 200);
    },
    /**
     * 视图联动
     */
    doVideoAndMap(videoAndMap = !this.videoAndMap, auto) {
      if (auto) {
        if (!this.screenItem.source.src) {
          this.autoVideoAndMap = true;
          return false;
        }
        this.autoVideoAndMap = false;
        if (this.videoAndMap) {
          return false;
        }
      }
      this.videoAndMap = videoAndMap; //视图联动显示、隐藏
      this.videoAndMapBig = 1;
      this.cloudControl(false); //关闭云台操控
      this.openTool("doVideoAndMap", videoAndMap);
    },
    /**
     * 快捷功能
     */
    quickToolClick(show = !this.quickTool) {
      this.quickTool = show;
      if (this.quickTool === false) {
        if (this.division === "1") {
          $("#videoDialog" + this.index).css({
            width: this.style.width,
            height: this.style.height,
            left: 0,
            top: 0,
            position: "relative",
          });
        }
      }
    },
    getCameraDetail() {
      const params = {
        deviceCode: this.deviceCode,
        channelCode: this.channelCode,
        tenantId: this.loginInfo.tenantId,
      };
      //获取摄像机标签
      queryVideoDetail(params).then((resp) => {
        if (resp.code === 200) {
          if (!this.lng || !this.lat) {
            this.lng = resp.data?.longitude;
            this.lat = resp.data?.latitude;
          }
          this.deviceName = resp.data?.deviceName;
          this.channelName = resp.data?.channelName;
        }
      });
    },
    /*点击PTZ*/
    ptzClick(ptzShow = !this.screenItem.ptzShow) {
      let sources = [
        {
          camera: {
            deviceCode: this.deviceCode,
            channelCode: this.channelCode,
            longitude: this.lng,
            latitude: this.lat,
          },
        },
      ];
      this.$set(this.screenItem, "sources", sources);
      this.$set(this.screenItem, "ptzShow", ptzShow);
      this.openTool("ptzClick", ptzShow);
    },
    /**
     * 监听浏览器窗口大小改变
     */
    windowResize() {
      this.checkFull();
    },
    getInitViewBox() {
      const winW = $(window).width();
      this.dragMaxWidth = parseInt(((this.ar.maxWidth || 1490) / 1920) * winW);
      this.dragMaxHeight = parseInt((this.dragMaxWidth * 9) / 16);
      this.dragMinWidth = parseInt(this.ar.minWidth || this.minWidth);
      this.dragMinHeight = parseInt((this.dragMinWidth * 9) / 16);
      this.commonToolMinWidth = parseInt((932 / 1920) * winW);
      this.commonToolMinHeight = parseInt((this.commonToolMinWidth * 9) / 16);
    },
    /**
     * 查询控制信息
     */
    getControllerInfo(flag) {
      if (flag !== 8) {
        this.$refs?.videoController.getOptioning(true, 50);
      }
      if (flag !== 9) {
        this.getCruisePause(this.screenItem);
      }
    },
    /**
     * 查询暂停巡航信息
     */
    getCruisePause(item) {
      clearTimeout(this.getCruisePauseTiming);
      this.getCruisePauseTiming = setTimeout(() => {
        const params = {
          deviceCode: this.deviceCode,
          channelCode: this.channelCode,
        };
        queryPauseResumePatrolInfo(params).then((resp) => {
          if (resp.code === 200 && Number(resp.data)) {
            this.$set(item, "cruisePause", true);
            this.cruisePauseTiming(item, Number(resp.data));
          } else {
            clearInterval(item.cruisePauseTiming);
            this.$set(item, "cruisePause", false);
          }
        });
      }, 50);
    },
    /**
     * 暂停巡航倒计时
     */
    cruisePauseTiming(item, endTime) {
      const _this = this;
      if (!endTime) {
        clearInterval(item.cruisePauseTiming);
        _this.$set(item, "cruisePause", false);
        return false;
      }
      clearInterval(item.cruisePauseTiming);
      item.cruisePauseTiming = setInterval(
        (function count() {
          if (endTime <= 0) {
            clearInterval(item.cruisePauseTiming);
            _this.$set(item, "cruisePause", false);
            return false;
          }
          const h = parseInt(endTime / 3600);
          const m = parseInt((endTime % 3600) / 60);
          const s = (endTime % 3600) % 60;

          let cruisePauseTime = `${String(m).padStart(2, 0)}:${String(
            s
          ).padStart(2, 0)}`;
          if (h > 0) {
            cruisePauseTime = `${String(h).padStart(2, 0)}:${cruisePauseTime}`;
          }
          _this.$set(item, "cruisePauseTime", cruisePauseTime);
          endTime--;
          return count;
        })(),
        1000
      );
    },
    /**
     * 暂停巡航操作
     */
    doCruisePause(item) {
      if (!this.checkPermissions("video:videoControlRole", true)) {
        return false;
      }
      this.getControllerInfo(9);
      const pause = !item.cruisePause;
      const pauseResumeStatus = pause ? "3" : "4"; //3: 暂停, 4: 恢复
      const params = {
        deviceCode: this.deviceCode,
        channelCode: this.channelCode,
        pauseResumeStatus,
      };
      pauseResumePatrol(params).then((resp) => {
        if (resp.code === 200) {
          this.$set(item, "cruisePause", pause);
          if (pause) {
            this.cruisePauseTiming(item, Number(resp.data));
          }
          const sTs = pause ? "巡航暂停成功" : "巡航恢复成功";
          $message.s(sTs);
        } else {
          $message.a(resp);
        }
      });
    },
    /**
     * 云台锁定显示
     */
    cloudLock({ isStart, endTime, optioning }, index) {
      let _this = this;
      if (isStart !== undefined) {
        clearInterval(_this.screenItem.cloudLockTiming);
        if (Date.now() >= endTime) {
          isStart = false;
        } else {
          _this.screenItem.cloudLockTiming = setInterval(
            (function count() {
              const over =
                parseInt(endTime / 1000) - parseInt(Date.now() / 1000);
              if (over <= 0) {
                clearInterval(_this.screenItem.cloudLockTiming);
                _this.$set(_this.screenItem, "cloudLock", false);
                _this.$refs?.videoController.gotoLockEvents(
                  _this.deviceCode + _this.channelCode
                );
                return false;
              }
              const h = parseInt(over / 3600);
              const m = parseInt((over % 3600) / 60);
              const s = (over % 3600) % 60;

              let cloudLockTime = `${String(m).padStart(2, 0)}:${String(
                s
              ).padStart(2, 0)}`;
              if (h > 0) {
                cloudLockTime = `${String(h).padStart(2, 0)}:${cloudLockTime}`;
              }
              _this.$set(_this.screenItem, "cloudLockTime", cloudLockTime);
              return count;
            })(),
            1000
          );
        }
        _this.$set(_this.screenItem, "cloudLock", !!isStart);
      }
      if (optioning !== undefined) {
        _this.$set(_this.screenItem, "optioning", optioning);
      }
    },
    /**
     * 云台锁定操作
     */
    doCloudLock() {
      if (!this.checkPermissions("video:videoControlRole", true)) {
        return false;
      }
      this.getControllerInfo(8);
      this.$refs?.videoController.gotoLockEvents();
    },
    /**
     * 计算位置
     */
    videoCalc(
      videoWidth = this.videoWidth,
      videoHeight = this.videoHeight,
      positonLeft = this.positonLeft,
      positonTop = this.positonTop
    ) {
      const winW = window.innerWidth;
      const winH = window.innerHeight;
      const scale = 16 / 9;
      let width, height, left, top, transform;
      if (videoHeight) {
        height = parseFloat(videoHeight);
        if (String(videoHeight).indexOf("%") !== -1) {
          height = (height / 100) * winH;
        }
        if (isNaN(height)) {
          height = this.minHeight;
        }
        if (height < this.minHeight) {
          this.myTransform = height / this.minHeight;
          height = this.minHeight;
        } else {
          this.myTransform = 1;
        }
        width = height * scale;
      } else {
        if (videoWidth) {
          width = parseFloat(videoWidth);
          if (String(videoWidth).indexOf("%") !== -1) {
            width = (width / 100) * winW;
          }
        } else {
          width = this.minWidth;
        }
        if (isNaN(width)) {
          width = this.minWidth;
        }
        if (width < this.minWidth) {
          this.myTransform = width / this.minWidth;
          width = this.minWidth;
        } else {
          this.myTransform = 1;
        }
        height = width / scale;
      }

      this.weatherRight = height < this.weatherAirHeight;

      if (this.division === "0") {
        if (positonTop) {
          top = parseFloat(positonTop);
          if (String(positonTop).indexOf("%") !== -1) {
            top = (top / 100) * winH;
          }
          if (isNaN(top)) {
            top = (winH - height) / 2;
          }
        } else {
          top = (winH - height) / 2;
        }
        if (positonLeft) {
          left = parseFloat(positonLeft);
          if (String(positonLeft).indexOf("%") !== -1) {
            left = (left / 100) * winW;
          }
          if (isNaN(left)) {
            left = (winW - width) / 2;
          }
        } else {
          left = (winW - width) / 2;
          if (this.defaultQuickTool) {
            left = left - 28;
          }
        }
      } else {
        left = 0;
        top = 0;
      }

      let myStyle = {
        width: parseInt(width) + "px",
        height: parseInt(height) + "px",
        left: left + "px",
        top: top + "px",
        "--border": this.all.border,
        "--ar-border": this.all.arBorder,
        "--checkedBorder": this.all.checkedBorder,
      };
      if (this.myTransform !== 1) {
        myStyle.transform = "scale(" + this.myTransform + ")";
      }
      if (this.transformOrigin) {
        myStyle["transform-origin"] = this.transformOrigin;
      }
      this.style = myStyle;
      this.toFitAr();
      $("[pid=" + this.pid + "] .video-dialog").css(this.style);
      return myStyle;
    },
    /**
     * AR定制化
     */
    toFitAr() {
      if (this.ar.style) {
        this.style = {
          ...this.style,
          ...this.ar.style,
        };
      }
    },
    initDicts() {
      this.getProtocolTypeOptions();
      getConfigByKey("video_weather_btn").then((resp) => {
        this.btnPowers["video_weather_btn"] = resp.data?.configValue;
      });
      getConfigByKey("video_air_btn").then((resp) => {
        this.btnPowers["video_air_btn"] = resp.data?.configValue;
      });
    },
    /**
     * 查询流协议类型列表
     */
    getProtocolTypeOptions() {
      this.getDicts("99").then((response) => {
        this.protocolTypeOptions = response.data;
      });
    },
    /**
     * 主子码流切换
     */
    changeStreamType() {
      const streamType = this.screenItem.source.streamType === 2 ? 1 : 2;
      this.doHabitPlayVideo(streamType, this.screenItem.source.protocolType);
    },
    /**
     * 暂停或播放
     */
    playOrPause(pause = !this.screenItem.pause, sdk) {
      if (!pause) {
        $("#videoSingleId" + this.index)
          .find(".vjs-play-control.vjs-paused, .video-tools .icon-bofang")
          .click();
      } else {
        $("#videoSingleId" + this.index)
          .find(".vjs-play-control.vjs-playing, .video-tools .icon-zanting")
          .click();
      }
      this.screenItem.pause = pause;
      if (!sdk) {
        this.$emit("pause", pause, this.index);
      }
    },
    /**
     * 静音
     */
    easyPlayMute(muted = !this.screenItem.muted) {
      if (!!this.screenItem.muted === !!muted) {
        return false;
      }
      this.openTool("easyPlayMute", muted);
      this.screenItem.muted = muted;
      this.$refs[this.screenItem.videoId].switchAudio();
      this.compelHasAudio = false;
      if (!this.hasAudio && this.all.hasAudio) {
        if (!muted) {
          this.compelHasAudio = true;
        }
        const src = this.screenItem.source.src;
        this.screenItem.source.src = "";
        this.$nextTick(() => {
          this.screenItem.source.src = src;
        });
      }
    },
    /**
     * 更改流协议类型
     */
    changeProtocol(protocolType) {
      this.doHabitPlayVideo(this.screenItem.source.streamType, protocolType);
    },
    /**
     * 摄像机 方向控制
     */
    platformControl(e, operType, operContent) {
      if (!this.checkPermissions("video:videoControlRole", operContent === 1)) {
        return false;
      }
      if (e) {
        e.preventDefault();
        if (operContent === 1) {
          this.cloudTouch = operType;
        } else {
          this.cloudTouch = false;
        }
      }
      let params = {
        deviceCode: this.deviceCode, //设备编码
        channelCode: this.channelCode, //通道编码
        customerCode: this.loginInfo.tenantId, //租户id
        operType: operType, //云台操作方向
        operContent: operContent, //转动开始/结束 1开始, 0结束
        step: this.cameraApertureSpeed, //速度
      };
      doPtzCmds(params).then((res) => {
        if (operContent == 0 && res.code != 200) {
          $message.a(res);
        }
        if (operContent == 0 && res.code == 200) {
          this.getCompass(null);
        }
      });
    },
    /**
     * 关联事件跳转
     */
    gotoRelevantEvents() {
      $v.jumpMenu(this, "/event?dc=" + this.deviceCode, true);
    },
    /**
     * 一件告警 弹框
     */
    gotoFastWarning() {
      this.outFullScreen();
      const params = {
        deviceCode: this.deviceCode,
        channelCode: this.channelCode,
        tenantId: this.loginInfo.tenantId,
      };
      //获取摄像机信息
      queryVideoDetail(params).then((res) => {
        if (res.code === 200) {
          this.oneKeyAlarmDatas = {
            longitude: this.lng,
            latitude: this.lat,
            deviceCode: this.deviceCode,
            channelCode: this.channelCode,
            deviceName: res?.data?.deviceName,
            channelName: res?.data?.channelName,
          };
          this.oneKeyAlarmDefaultPic = false;
          this.oneKeyAlarmShow = true;
          this.screenshot(1).then((back) => {
            this.oneKeyAlarmDefaultPic = back.file;
          });
        } else {
          $message.a(res);
        }
      });
    },
    /**
     * 一件告警 关闭
     */
    oneKeyAlarmHide() {
      this.oneKeyAlarmShow = false;
    },
    /**
     * 获取记录视频播放喜好
     */
    doHabitPlayVideo(streamType, protocolType) {
      const habitKey = "real" + "_" + this.deviceCode + "_" + this.channelCode;
      if (!streamType) {
        // 获取用户视频流设置
        getUserHabit({ habitKey: habitKey }).then((res) => {
          if (res.code == 200 && res.data.indexOf(",") > 0) {
            streamType = res.data.split(",")[0];
            protocolType = res.data.split(",")[1];
          }
          this.doPlayVideo(streamType, protocolType);
        });
      } else {
        streamType = Number(streamType) || 1;
        protocolType =
          Number(protocolType) || this.$store.getters.protocolTypeNew;
        this.doPlayVideo(streamType, protocolType, () => {
          const val = streamType + "," + protocolType;
          // 获取用户视频流设置
          setUserHabit({ habitKey: habitKey, habitValue: val });
        });
      }
    },
    /**
     * 视频播放
     */
    doPlayVideo(streamType, protocolType, success) {
      streamType = Number(streamType) || 1;
      protocolType = Number(protocolType) || store.getters.protocolTypeNew;
      if (this.screenItem.source) {
        this.screenItem.source.src = "";
      }
      if (this.all.hasPlayBackFile === false) {
        return false;
      }
      this.getVideoStream(protocolType, streamType)
        .then((res) => {
          this.screenItem = this.defaultScreenItem;
          if (this.all.hasPlayBackFile === false) {
            this.screenItem.source.src = "";
            return false;
          }
          this.screenItem.muted = true;
          this.compelHasAudio = false;
          this.screenItem.source.streamType = res.streamType;
          this.screenItem.source.streamTypeName =
            res.streamType === 2 ? "子码流" : "主码流";
          this.screenItem.source.streamSwitchFlag = res.streamSwitchFlag;
          this.screenItem.source.src = res.streamUrl;
          this.streamControlId = res.streamControlId;
          this.$emit("getstreamUrl", {
            url: res.streamUrl,
            name: this.channelName,
          });
          this.screenItem.source.protocolType = String(protocolType);
          this.screenItem.videoId = "videoSingleIdRef" + this.index;
          this.$set(this.screenItem, "recording", 0);
          this.toLookHere();
          this.gotoPTZ();
          this.gotoPreset();
          this.openCall();
          this.openVideoAndMap();
          this.$emit("playStatus", true, this.index);
          if (this.autoVideoAndMap) {
            this.doVideoAndMap(true, true);
          }
          this.autoOpenTool();
          if (this.speed > 0) {
            this.playbackControl(this.speed);
          }
          success && success();
        })
        .catch(() => {
          this.$emit("playStatus", false, this.index);
          this.$emit("error");
        });
      let _this = this;
      //绑定右键
      $("#videoSingleId" + this.index).on("contextmenu", function (e) {
        if (_this.videoAndMap || _this.recordLook) {
          return false;
        }
        $("#divmenu" + _this.index)
          .css({
            left:
              Math.min(
                e.clientX - $(this).offset().left,
                ($(this).width() - 100) * _this.myTransform
              ) / _this.myTransform,
            top:
              Math.min(
                e.clientY - $(this).offset().top,
                ($("#videoSingleId" + _this.index).height() -
                  $("#divmenu" + _this.index).height() -
                  5) *
                  _this.myTransform
              ) / _this.myTransform,
          })
          .show();
      });
      //点击左键 自定义菜单消失
      $("#videoSingleId" + this.index).on("click", function () {
        $("#divmenu" + _this.index).hide();
      });
    },
    /**
     * 自动看这里
     */
    async toLookHere() {
      if (this.lookHere) {
        turnToPtzByPointAngle(this.lookHere.ptzInfo).then((res) => {
          if (res.code != 200 || !this.lookHere.turnCallBack) {
            return false;
          }
          let param = {
            callBackMethod: this.lookHere.turnCallBack,
            turnData: res.data,
          };
          $("iframe.iframe-container").each(function () {
            if ($(this).is(":visible")) {
              $(this).get(0).contentWindow.postMessage(param, "*");
            }
          });
        });
      }
    },
    /**
     * 自动转到ptz
     */
    async gotoPTZ() {
      if (!this.all?.toPTZ) {
        return false;
      }
      const { pan, tilt, zoom, ptzIsEsc } = this.all.toPTZ;
      const params = {
        deviceCode: this.deviceCode,
        channelCode: this.channelCode,
        pan,
        tilt,
        zoom,
        ptzIsEsc, //值为1：转义前ptz；值为空转义后ptz
      };
      doPtzLocationCmd(params);
    },
    /**
     * 自动转到预置位
     */
    async gotoPreset() {
      if (!this.all?.toPreset) {
        return false;
      }
      if (!this.checkPermissions("video:videoPreset")) {
        return false;
      }
      const { presetId } = this.all.toPreset;
      const params = {
        deviceCode: this.deviceCode, //设备编码
        channelCode: this.channelCode, //通道编码
        presetId, //预置位 id
        customerCode: this.tenantId, //租户id
      };
      doControlPreset(params);
    },
    /**
     * 自动打开语音对讲
     */
    openCall() {
      if (!this.screenItem.source.src) {
        this.$emit("intercomBack", 2);
        return false;
      }
      if (this.all?.call) {
        this.voiceIntercom(true);
      }
    },
    /**
     * 自动打开视图联动
     */
    openVideoAndMap() {
      if (this.all?.openVideoAndMap) {
        this.doVideoAndMap(true);
      }
    },
    /**
     * 移除视频
     */
    removeVideo() {
      const isFull = this.checkFull();
      if (isFull) {
        this.outFullScreen();
      }
      this.showVideos = false;
      this.$emit("closed", this.index);
      clearInterval(this.screenItem.recordTiming);
    },
    /**
     * 获取视频流
     */
    getVideoStream(
      protocolType = store.getters.protocolTypeNew,
      streamType = 1
    ) {
      return new Promise((resolve, reject) => {
        if (!this.ar.playBack) {
          const params = {
            deviceCode: this.deviceCode, //设备编码
            channelCode: this.channelCode, //通道编码
            customerCode: this.loginInfo.tenantId, //租户id
            streamType: streamType, //码流类型 1-主码流；2-子码流；
            protocolType: protocolType || store.getters.protocolTypeNew, //协议类型
            netType: store.getters.netType,
            deviceType: this.all.deviceType || "",
          };
          getVideoRealtimeUrl(params)
            .then((res) => {
              if (res.code == 200) {
                resolve(res.data);
              } else {
                $message.a(res);
                reject(res);
              }
            })
            .catch((err) => {
              console.log("rejected", err);
              reject(err);
            });
        } else {
          const params = {
            deviceCode: this.deviceCode, //设备编码
            channelCode: this.channelCode, //通道编码
            startTime: this.ar.playBack[0],
            endTime: this.ar.playBack[1],
            protocolType: protocolType || store.getters.protocolTypeNew, //协议类型
            storageType: 1,
            netType: store.getters.netType,
            frontStreamUuid: this.streamUuid, // 流uuid
          };
          getVideoPlaybackUrl(params)
            .then((res) => {
              if (res.code == 200) {
                this.streamUuid = res.data.streamUuid;
                resolve(res.data);
              } else {
                $message.a(res);
                reject(res);
              }
            })
            .catch((err) => {
              console.log("rejected", err);
              reject(err);
            });
        }
      });
    },
    /**
     * 切换播放模式
     */
    changePlayMode(val, updateHabit) {
      if (this.screenItem.source) {
        this.doHabitPlayVideo(
          this.screenItem.source.streamType,
          this.screenItem.source.protocolType
        );
      }
      if (!updateHabit) {
        setUserHabit({ habitKey: "playMode", habitValue: val });
      }
    },
    reloadVideo() {
      this.doPlayVideo(
        this.screenItem.source.streamType,
        this.screenItem.source.protocolType
      );
    },
    adaptBySelf() {
      this.easyStretch = !this.easyStretch;
    },
    /**
     * 抓视频 结束回调
     */
    recordEnd(b) {
      if (!this.screenItem.recording) {
        return false;
      }
      if (!b) {
        this.switchRecordingUnts === undefined && $message.w("请重新录制。");
      } else {
        this.switchRecordingUnts === undefined && $message.s("视频录制成功");
      }
      this.$set(this.screenItem, "recording", 0);
      clearInterval(this.screenItem.recordTiming);
      clearTimeout(this.screenItem.recordTimeout);
      if (this.arloadVideo) {
        this.arloadVideo = false;
        this.$emit("closeAll");
      }
    },
    /**
     * 抓视频
     */
    switchRecording(stop, status) {
      this.switchRecordingUnts = status;
      if (stop === false) {
        if (this.screenItem.recording) {
          this.$refs[this.screenItem.videoId].switchRecording(true);
        }
        return false;
      }
      if (
        this.screenItem.recording === 2 ||
        (status !== undefined && !!this.screenItem.recording === !!status)
      ) {
        return false;
      }
      clearInterval(this.screenItem.recordTiming);
      clearTimeout(this.screenItem.recordTimeout);
      if (!this.screenItem.recording) {
        this.$refs[this.screenItem.videoId].switchRecording();
        this.$set(this.screenItem, "recording", 1);
        const startTime = Date.now();
        const t = 100;
        let time = 0;
        this.$set(this.screenItem, "recordTime", time);
        this.screenItem.recordTiming = setInterval(() => {
          time += t;
          if (time % 3000 === 0) {
            time = Math.round((Date.now() - startTime) / 1000) * 1000;
          }
          if (time >= 300000) {
            this.switchRecording();
          }
          this.$set(this.screenItem, "recordTime", time);
        }, t);
        return false;
      }
      if (this.screenItem.recordTime < 3000) {
        this.$refs[this.screenItem.videoId].switchRecording(true);
        this.recordEnd(false);
        return false;
      }
      this.$refs[this.screenItem.videoId].switchRecording();
      this.$set(this.screenItem, "recording", 2);
      this.screenItem.recordTimeout = setTimeout(() => {
        if (this.screenItem.recording === 2) {
          this.$set(this.screenItem, "recording", 0);
          this.switchRecordingUnts === undefined && $message.w("请重新录制。");
        }
      }, 4000);
    },
    /**
     * AR大屏抓视频
     */
    switchRecordingAR() {
      this.arloadVideo = true;
    },
    switchRecordingARN() {
      this.arloadVideo = false;
    },
    /**
     * 快照
     */
    screenshot(flag, unTs) {
      return new Promise((resolve) => {
        const $dom = this.$refs[this.screenItem.videoId];
        try {
          if (flag) {
            $dom.snapshot((back) => {
              resolve(back);
            });
          } else {
            $dom.snapshot();
            !unTs && $message.s("抓图成功");
          }
        } catch (e) {
          if (!flag && !unTs) {
            $message.e("抓图失败");
          }
        }
      });
    },
    /**
     * 快照 操作
     */
    screenshotOpt(type) {
      clearTimeout(this.screenshotAutoClose);
      if (type === 1) {
        this.screenshotBig = !this.screenshotBig;
      }
      if (type === 2) {
        let imgName = "快照_";
        const date = new Date();
        const yyyy = date.getFullYear();
        const mm = ("0" + (date.getMonth() + 1)).substr(-2);
        const dd = ("0" + date.getDate()).substr(-2);
        const hh = ("0" + date.getHours()).substr(-2);
        const sm = ("0" + date.getMinutes()).substr(-2);
        const ss = ("0" + date.getSeconds()).substr(-2);
        imgName += yyyy + mm + dd + hh + sm + ss;
        let a = document.createElement("a");
        a.href = this.screenshotImg;
        a.download = imgName;
        a.click();
        this.screenshotClose();
      }
      if (type === 3) {
        this.screenshotClose();
      }
    },
    /**
     * 快照 关闭
     */
    screenshotClose() {
      this.screenshotImg = false;
      this.screenshotKeep = false;
      this.screenshotBig = false;
    },
    /**
     * 全屏
     */
    fullScreen() {
      Bus.$emit("dblClickVideo", true);
      const eleId = "videoDialog" + this.index;
      const isFull = this.checkFull(1);
      window.fullScreenId = false;
      console.log("-----判断全屏" + isFull + "----");

      if (!isFull) {
        window.videoCompFull = true;
        this.maxScreenElement();

        this.doFullScreen(document.body);
        window.fullScreenId = eleId;
      } else {
        this.outFullScreen();
      }
      clearTimeout(this.resizeTiming);
      this.resizeTiming = setTimeout(() => {
        this.checkFull();
      }, 300);
    },
    /**
     * 监听用户按下esc
     */
    watchKeyESC() {
      const _this = this;
      const handleResize = () => {
        const isFull = this.checkFull(1);
        console.log(
          "fullscreenchang触发,isFull",
          isFull,
          _this.fullScreenStatus
        );

        if (!isFull) {
          //要执行的动作
          _this.resizeScreenElement();
          window.removeEventListener("fullscreenchange", handleResize);
        }
      };
      window.addEventListener("fullscreenchange", handleResize);
    },
    doFullScreen(element) {
      if (element.requestFullscreen) {
        element.requestFullscreen();
      } else if (element.mozRequestFullScreen) {
        /* Firefox */
        element.mozRequestFullScreen();
      } else if (element.webkitRequestFullscreen) {
        /* Chrome, Safari 和 Opera */
        element.webkitRequestFullscreen();
      } else if (element.msRequestFullscreen) {
        /* IE/Edge */
        element.msRequestFullscreen();
      }
    },
    /**
     * 放到最大
     */
    maxScreenElement() {
      this.fullScreenStatus = true;
      const $videoPlayBody = $("#videoDialog" + this.index);
      const { offsetLeft, offsetTop, offsetWidth, offsetHeight } =
        $videoPlayBody[0];
      this.fullScreenOldItem = {
        offsetLeft,
        offsetTop,
        offsetWidth,
        offsetHeight,
      };
      this.classIsFull = true;
      const $pageView = $videoPlayBody.closest(".page-view");
      if ($pageView.length > 0) {
        // 如果找到了class为a的div，则执行以下代码
        console.log($pageView); // 打印找到的元素
        // 你可以对$closestDiv进行进一步的操作，比如添加样式、绑定事件等
        $pageView.css({
          overflow: "visible",
          zIndex: "99999",
        });
      }
      this.watchKeyESC();
    },
    /**
     * 还原原来大小
     */
    resizeScreenElement() {
      const $videoPlayBody = $("#videoDialog" + this.index);
      this.classIsFull = false;
      const $pageView = $videoPlayBody.closest(".page-view");
      if ($pageView.length > 0) {
        // 如果找到了class为a的div，则执行以下代码
        console.log($pageView); // 打印找到的元素
        // 你可以对$closestDiv进行进一步的操作，比如添加样式、绑定事件等
        $pageView.css({
          overflow: "hidden",
          zIndex: "6",
        });
      }
      this.fullScreenStatus = false;
      this.resetSize();
    },
    /**
     * 恢复大小位置
     */
    resetSize() {
      if (this.fullScreenOldItem) {
        const $videoPlayBody = $("#videoDialog" + this.index);
        const { offsetLeft, offsetTop, offsetWidth, offsetHeight } =
          this.fullScreenOldItem;
        $videoPlayBody.css({
          width: offsetWidth,
          height: offsetHeight,
          left: offsetLeft,
          top: offsetTop,
        });
        let count = 0;
        this.resetSizeTiming = setInterval(() => {
          count += 5;
          if (count > 200) {
            clearInterval(this.resetSizeTiming);
            return false;
          }
          $videoPlayBody.css({
            width: offsetWidth,
            height: offsetHeight,
            left: offsetLeft,
            top: offsetTop,
          });
        }, 5);
      }
      this.fullScreenOldItem = null;
    },
    /**
     * 退出全屏
     */
    outFullScreen() {
      this.resizeScreenElement();

      Bus.$emit("dblClickVideo", false);
      window.fullScreenId = false;
      let fullscreenEnabled =
        document.fullscreenEnabled ||
        document.webkitFullscreenEnabled ||
        document.mozFullScreenEnabled ||
        document.msFullscreenEnabled;
      if (!fullscreenEnabled) {
        return false;
      }
      let fullscreenElement =
        document.fullscreenElement ||
        document.webkitFullscreenElement ||
        document.mozFullScreenElement ||
        document.msFullscreenElement;
      if (fullscreenElement !== undefined) {
        if (document.exitFullscreen) {
          document.exitFullscreen();
        } else if (document.msExitFullscreen) {
          document.msExitFullscreen();
        } else if (document.mozCancelFullScreen) {
          document.mozCancelFullScreen();
        } else if (document.webkitExitFullscreen) {
          document.webkitExitFullscreen();
        }
      }
    },
    // 判断全屏
    checkFull(type) {
      //判断浏览器是否处于全屏状态 （需要考虑兼容问题）
      var isFull =
        document.mozFullScreen ||
        document.fullScreen ||
        document.webkitIsFullScreen ||
        document.webkitRequestFullScreen ||
        document.mozRequestFullScreen ||
        document.msFullscreenEnabled;
      clearTimeout(this.resizeTimming);
      if (!isFull) {
        isFull = false;
        window.fullScreenId = false;
        this.resizeTimming = setTimeout(() => {
          window.videoCompFull = false;
        }, 300);
      }
      if (isFull && window.fullScreenId !== "videoDialog" + this.index) {
        isFull = false;
      }
      this.fullScreenFlag = null;
      setTimeout(() => {
        this.fullScreenFlag = isFull;
        if (isFull) {
          Bus.$emit("dblClickVideo", false);
        }
        !type && this.enlargeSuanFaShibieAndPingBiQuYu();
      });
      return isFull;
    },
    enlargeSuanFaShibieAndPingBiQuYu() {
      if (
        this.screenItem.suanFaShiBie === false &&
        this.screenItem.pingBiQuYu !== false
      ) {
        this.initSuanfaCanvasPingbiquyu();
        this.getMakeRoof(
          this.screenItem.pingBiQuYuArry,
          "#CA3931",
          "rgba(80,18,16,0.3)",
          this.screenItem.pingBiQuYu,
          this.index,
          "pingbiquyu"
        );
      }
    },
    /**
     * 在线模式-云台控制 zzh 20220210
     */
    cloudControl(showVideoCloud = !this.screenItem.showVideoCloud) {
      this.screenItem.showVideoCloud = showVideoCloud;
      this.openTool("cloudControl", showVideoCloud);
      this.fitCloudAndMap(1);
    },
    /**
     * 地图 zzh 20220210
     */
    gisControl(showVideoMap = !this.screenItem.showVideoMap) {
      if (!this.lng || !this.lat) {
        $message.e("未获取到坐标地址");
        return false;
      }
      this.screenItem.showVideoMap = showVideoMap;
      this.openTool("gisControl", showVideoMap);
      if (this.screenItem.showVideoMap) {
        this.initCTMap();
      } else {
        if (this.map && this.removeEndPoint) {
          this.mapMap.destroy();
          this.removeEndPoint = null;
        }
      }
      this.fitCloudAndMap(2);
    },
    /**
     * 适配云台操控和地图同时打开
     */
    async fitCloudAndMap(type) {
      clearTimeout(this.fitCloudAndMapTiming);
      if (!this.screenItem.showVideoCloud || !this.screenItem.showVideoMap) {
        return false;
      }
      this.fitCloudAndMapTiming = setTimeout(() => {
        if (this.$refs.cloudControl.offsetTop - 40 < 0) {
          if (type === 1) {
            //打开云台
            this.gisControl(false);
          }
          if (type === 2) {
            //打开地图
            this.cloudControl(false);
          }
        }
      }, 600);
    },
    /**
     * 初始化高德2.0版本地图
     */
    initCTMap() {
      initCTMap(
        `mapSingleVideo${this.suffix}${this.index}`,
        [this.lng, this.lat],
        1,
        12,
        (resmap, resmapMap) => {
          this.map = resmap;
          this.mapMap = resmapMap;
          this.doMarker();
        }
      );
    },
    /**
     * 地图打点
     */
    doMarker() {
      setZoomAndCenter(this.map, this.lng, this.lat, 12);
      let img = {
        imgPath: this.isGt ? monitorOnline_g : monitorOnline,
        offset: [-13, -15],
        imgWidth: 30,
        imgHeight: 30,
      };
      const marker = commAddMarker(this.map, this.lng, this.lat, null, img);
      this.removeEndPoint = marker;
    },

    /**
     * 点击icon切换颜色 zzh 20220210
     */
    changeBgColor(event) {
      if (event.target.classList.value.indexOf("bgcolorFh") == -1) {
        // 点击
        event.target.classList.add("bgcolorFh");
        return true;
      } else {
        // 取消
        event.target.classList.toggle("bgcolorFh");
        return false;
      }
    },
    /**
     * 自适应 zzh 20220210
     */
    changeStretch() {
      this.easyStretch = !this.easyStretch;
    },
    // 算法识别区域按钮
    selectAlgorithmDistinguish(
      suanfashibieShow = !this.suanfashibieShow,
      close
    ) {
      this.suanfashibieShow = suanfashibieShow;
      if (!close) {
        this.openTool("selectAlgorithmDistinguish", suanfashibieShow);
      }
      const index = this.index;
      //打开
      if (suanfashibieShow) {
        let param = {
          deviceCode: this.deviceCode, //设备编码
          channelCode: this.channelCode, //通道编码
          tenantId: this.loginInfo.tenantId, //租户id
          taskType: "1", //后端算法
          status: "0", //启用状态
        };
        this.drawData.deviceCode = this.deviceCode;
        this.drawData.channelCode = this.channelCode;
        //获取下拉框中的数据
        queryAlgorithm(param).then((res) => {
          for (let i = 0; i < res.rows.length; i++) {
            res.rows[i].active = 0;
          }
          let params = {
            index: index,
            list: res.rows,
          };
          this.suanfashibieOptionsList[index] = params;
          for (let k = 0; k < this.suanfashibieOptionsList.length; k++) {
            if (!this.suanfashibieOptionsList[k]) {
              this.suanfashibieOptionsList[k] = {
                index: k,
                list: [],
              };
            }
          }
          this.suanfashibieOptionsList = JSON.parse(
            JSON.stringify(this.suanfashibieOptionsList)
          );
        });
        $("#suanfashibie-select" + index).show();
        $("#suanfashibie-icon-top" + index).show();
        $("#suanfashibie-icon-bottom" + index).hide();
        $("#suanfashibie-select-options" + index).show();
      } else {
        //告警屏蔽区域隐藏
        //关闭
        $("#suanfashibie-select" + index).hide();
        $("#suanfashibie-tip" + index).hide();
      }
    },
    // 点击算法识别区域下拉框
    suanfashibieSelectFunc(index) {
      let displayValue = $("#suanfashibie-select-options" + index).css(
        "display"
      );
      if (displayValue == "none") {
        $("#suanfashibie-select-options" + index).show();
        $("#suanfashibie-icon-bottom" + index).hide();
        $("#suanfashibie-icon-top" + index).show();
      } else {
        $("#suanfashibie-select-options" + index).hide();
        $("#suanfashibie-icon-bottom" + index).show();
        $("#suanfashibie-icon-top" + index).hide();
      }
    },
    // 选中算法识别区域数据
    algorithmClickClose(data, index, j) {
      this.screenItem.suanFaShiBie = false;
      this.screenItem.pingBiQuYu = false;
      //处理显示
      this.suanfashibieOptionsList = JSON.parse(
        JSON.stringify(this.suanfashibieOptionsList)
      );
      if (this.algorithmChooseList.length === 0) {
        this.algorithmChooseList.push({
          presetId: data.presetId,
          configId: data.configId,
          data: data,
        });
        this.suanfashibieOptionsList[index].list[j].active = 1;
      } else {
        if (
          (data.presetId &&
            this.algorithmChooseList[0].presetId === data.presetId) ||
          (data.posType === 1 &&
            this.algorithmChooseList[0].presetId === undefined)
        ) {
          //选择的和之前的是同一通道
          let flag = true;
          for (let list of this.algorithmChooseList) {
            if (list.configId === data.configId) {
              flag = false;
            }
          }
          if (flag) {
            this.algorithmChooseList.push({
              presetId: data.presetId,
              configId: data.configId,
              data: data,
            });
          }
          this.suanfashibieOptionsList[index].list[j].active = 1;
        } else {
          this.algorithmChooseList = [
            {
              presetId: data.presetId,
              configId: data.configId,
              data: data,
            },
          ];
          for (
            let i = 0;
            i < this.suanfashibieOptionsList[index].list.length;
            i++
          ) {
            if (i == j) {
              this.suanfashibieOptionsList[index].list[i].active = 1;
            } else {
              this.suanfashibieOptionsList[index].list[i].active = 0;
            }
          }
        }
      }
      // 如果是预置位，转到预置位
      if (data.posType == "2") {
        let params = {
          deviceCode: data.deviceCode, //设备编码
          channelCode: data.channelCode, //通道编码
          presetId: data.presetId, //预置位 id
          tenantId: this.loginInfo.tenantId, //租户id
        };
        doControlPreset(params).then((res) => {
          if (res.code === 200) {
            this.suanFaShiBieDoDrawBack(index);
            // this.getMakeRoof(JSON.parse(data.points),'#55C3F6','rgba(241,161,57,0.3)', data, index, 'suanfashibie')
          } else {
            $message.a(res);
            this.suanfashibieOptionsList[index].list[j].active = 0;
            return false;
          }
        });
      } else {
        setTimeout(() => {
          this.suanFaShiBieDoDrawBack(index);
          // this.getMakeRoof(JSON.parse(data.points),'#55C3F6','rgba(241,161,57,0.3)', data, index, 'suanfashibie')
        }, 200);
      }
    },
    goPreset(data) {
      let params = {
        deviceCode: data.deviceCode, //设备编码
        channelCode: data.channelCode, //通道编码
        presetId: data.presetId, //预置位 id
        tenantId: this.loginInfo.tenantId, //租户id
      };
      doControlPreset(params).then((res) => {
        if (res.code === 200) {
          $message.a(res);
        } else {
          $message.a(res);
        }
      });
    },
    algorithmClickOpen(data, index, j) {
      this.algorithmChooseList.map((item, index) => {
        if (item.data.configId === data.configId) {
          this.algorithmChooseList.splice(index, 1);
        }
      });
      this.suanfashibieOptionsList[index].list[j].active = 0;
      this.suanFaShiBieDoDrawBack(index);
    },
    algorithmHighlight(data, index, j) {
      for (
        let i = 0;
        i < this.suanfashibieOptionsList[index].list.length;
        i++
      ) {
        if (i === j) {
          this.$set(
            this.suanfashibieOptionsList[index].list[i],
            "highlight",
            1
          );
          this.$refs["suanfashibieDrawArea" + index].doDrawChoose(
            data.configId
          );
        } else {
          this.$set(
            this.suanfashibieOptionsList[index].list[i],
            "highlight",
            0
          );
        }
      }
    },
    suanFaShiBieDoDrawBack(index) {
      let draw = [];
      let list = this.algorithmChooseList;
      for (const i in list) {
        let allPoints = JSON.parse(list[i].data.points);
        for (const j in allPoints) {
          let arr = allPoints[j].moniPointList;
          arr = arr.map((p) => {
            return {
              x: p.percentX,
              y: p.percentY,
            };
          });
          draw.push({
            id: list[i].data.configId,
            type: allPoints[j].monitorType,
            points: arr,
            direction: [],
          });
        }
        const tripThread = list[i].data.tripThread
          ? JSON.parse(list[i].data.tripThread)
          : [];
        for (const item of tripThread) {
          const threadLineReturn = item.threadLine;
          const directionReturn = item.direction;
          let direction = [];
          let points = [];
          for (const threadLineElement of threadLineReturn) {
            points.push({
              x: threadLineElement.percentX,
              y: threadLineElement.percentY,
            });
          }
          for (const directionElement of directionReturn) {
            direction.push({
              x: directionElement.percentX,
              y: directionElement.percentY,
            });
          }
          draw.push({
            id: list[i].data.configId,
            type: 2,
            points: points,
            direction: direction,
          });
        }
      }
      this.$refs["suanfashibieDrawArea" + index].doDrawBack(draw);
    },
    // 告警屏蔽区域按钮
    selectAlarmShield(gaojingpingbiShow = !this.gaojingpingbiShow, close) {
      this.gaojingpingbiShow = gaojingpingbiShow;
      if (!close) {
        this.openTool("selectAlarmShield", gaojingpingbiShow);
      }

      const index = this.index;
      //打开
      if (gaojingpingbiShow) {
        let param = {
          channelCode: this.channelCode, //通道编码
        };
        //获取下拉框中的数据-客户视角
        queryAreaSuppressList(param).then((res) => {
          for (let i = 0; i < res.data.length; i++) {
            res.data[i].active = 0;
          }
          let params = {
            index: index,
            list: res.data,
          };
          this.pingbiquyuOptionsList[index] = params;
          for (let k = 0; k < this.pingbiquyuOptionsList.length; k++) {
            if (!this.pingbiquyuOptionsList[k]) {
              this.pingbiquyuOptionsList[k] = {
                index: k,
                list: [],
              };
            }
          }
          this.pingbiquyuOptionsList = JSON.parse(
            JSON.stringify(this.pingbiquyuOptionsList)
          );
        });

        $("#pingbiquyu-select" + index).show();
        $("#pingbiquyu-icon-top" + index).show();
        $("#pingbiquyu-icon-bottom" + index).hide();
        $("#pingbiquyu-select-options" + index).show();
      } else {
        //关闭
        $("#pingbiquyu-select" + index).hide();
        $("#pingbiquyu-tip" + index).hide();
        $("#pingbiquyu" + index).hide();
      }
    },
    // 点击告警屏蔽区域下拉框
    pingbiquyuSelectFunc(index) {
      let displayValue = $("#pingbiquyu-select-options" + index).css("display");
      if (displayValue == "none") {
        $("#pingbiquyu-select-options" + index).show();
        $("#pingbiquyu-icon-bottom" + index).hide();
        $("#pingbiquyu-icon-top" + index).show();
      } else {
        $("#pingbiquyu-select-options" + index).hide();
        $("#pingbiquyu-icon-bottom" + index).show();
        $("#pingbiquyu-icon-top" + index).hide();
      }
    },
    // 选中告警屏蔽区域数据
    pingbiquyuClick(data, index, j) {
      this.screenItem.suanFaShiBie = false;
      this.screenItem.pingBiQuYu = false;
      this.screenItem.pingBiQuYu = data;
      //处理显示
      this.pingbiquyuOptionsList = JSON.parse(
        JSON.stringify(this.pingbiquyuOptionsList)
      );
      for (let i = 0; i < this.pingbiquyuOptionsList[index].list.length; i++) {
        this.pingbiquyuOptionsList[index].list[i].active = i == j ? 1 : 0;
      }
      if (this.pingbiquyuOptionsList[index].list[j].active == 1) {
        $("#pingbiquyu-select-options" + index).hide();
        $("#pingbiquyu-icon-bottom" + index).show();
        $("#pingbiquyu-icon-top" + index).hide();
        this.initSuanfaCanvasPingbiquyu(index);
        $("#pingbiquyu" + index).show();
        let param = {
          areaId: data.areaId,
        };
        queryAreaSuppress(param).then((res) => {
          if (res.data.length > 0) {
            let arry = [
              {
                moniPointList: JSON.parse(res.data[0].points),
              },
            ];
            this.screenItem.pingBiQuYuArry = false;
            this.screenItem.pingBiQuYuArry = arry;
            let paramData = {
              deviceCode: res.data[0].deviceCode, // 设备编码
              channelCode: res.data[0].channelCode, // 通道编码
              pan: res.data[0].pointsP, // p值
              tilt: res.data[0].pointsT, // t值
              zoom: res.data[0].pointsZ, // z值
              ptzIsEsc: "", //值为1：转义前ptz；值为空转义后ptz
            };
            doPtzLocationCmd(paramData).then((response) => {
              if (response.code == 200) {
                this.getMakeRoof(
                  arry,
                  "#CA3931",
                  "rgba(80,18,16,0.3)",
                  data,
                  index,
                  "pingbiquyu"
                );
              } else {
                $message.a(response.msg);
                this.isTenantHandle(index, j);
              }
            });
          }
        });
      } else {
        $("#pingbiquyu" + index).hide();
        $("#pingbiquyu-tip" + index).hide();
      }
    },
    isTenantHandle(index, j) {
      if (this.isTenant) {
        this.pingbiquyuOptionsList[index].list[j].active = 0;
      }
    },
    // 选中告警屏蔽区域数据-双击
    pingbiquyuDbClick() {
      //处理显示
      this.pingbiquyuOptionsList = JSON.parse(
        JSON.stringify(this.pingbiquyuOptionsList)
      );
      let list = this.pingbiquyuOptionsList[this.index].list;
      for (let i = 0; i < list.length; i++) {
        if (list[i].active == 1) {
          this.initSuanfaCanvasPingbiquyu(this.index);
          this.areaSuppressHandle(list[i]);
        }
      }
    },
    areaSuppressHandle(list) {
      let param = {
        areaId: list.areaId,
      };
      queryAreaSuppress(param).then((res) => {
        if (res.data.length > 0) {
          let arry = [
            {
              moniPointList: JSON.parse(res.data[0].points),
            },
          ];
          let paramData = {
            deviceCode: res.data[0].deviceCode, // 设备编码
            channelCode: res.data[0].channelCode, // 通道编码
            pan: res.data[0].pointsP, // p值
            tilt: res.data[0].pointsT, // t值
            zoom: res.data[0].pointsZ, // z值
            ptzIsEsc: "", //值为1：转义前ptz；值为空转义后ptz
          };
          doPtzLocationCmd(paramData).then((response) => {
            if (response.code == 200) {
              this.getMakeRoof(
                arry,
                "#CA3931",
                "rgba(80,18,16,0.3)",
                list,
                this.index,
                "pingbiquyu"
              );
            } else {
              $message.a(response.msg);
            }
          });
        }
      });
    },
    initSuanfaCanvasPingbiquyu(index = this.index) {
      let id = "pingbiquyu-canvas" + index;
      let w, h;
      const choosedVideo = $("#videoPlay" + index);
      w = choosedVideo.width();
      h = choosedVideo.height();
      console.log(`初始化算法标绘canvas的宽:${w}px;高:${h}px;`);
      this.drawForm.width = w;
      this.drawForm.height = h;
      this.drawForm.videoStyle = "width: " + w + "px; height: " + h + "px";
      const $videoCanvas = document.getElementById(id);
      if ($videoCanvas) {
        $videoCanvas.width = w;
        $videoCanvas.height = h;
      }
      this.initFabric(id);
    },
    /**
     * 初始化fabric
     */
    initFabric(id) {
      this.fabricObject.fabricObj = null;
      this.fabricObject.fabricObj = new fabric.Canvas(id);
      console.log("初始化fabric的id:" + id);
      this.fabricObject.fabricObj.selection = false;
      this.fabricObject.fabricObj.on({
        "mouse:down": (e) => {
          if (!this.drawForm.drawing) {
            return;
          }
          if (this.fabricObject.drawingObject.type == "roof") {
            this.fabricObject.fabricObj.selection = false;
            this.fabricObject.mouseFrom.x = e.pointer.x;
            this.fabricObject.mouseFrom.y = e.pointer.y;
            let a = {};
            a["x"] = this.fabricObject.mouseFrom.x;
            a["y"] = this.fabricObject.mouseFrom.y;
            this.fabricObject.roofPoints.push(a);
            var points = [a.x, a.y, a.x, a.y];
            this.fabricObject.lines.push(
              new fabric.Line(points, {
                strokeWidth: 3,
                selectable: false,
                stroke: "red",
              })
            );
            this.fabricObject.fabricObj.add(
              this.fabricObject.lines[this.fabricObject.lineCounter]
            );
            this.fabricObject.lineCounter++;
          }
        },
        "mouse:move": (e) => {
          if (!this.drawForm.drawing) {
            return;
          }
          if (
            this.fabricObject.lines[0] !== null &&
            this.fabricObject.lines[0] !== undefined &&
            this.fabricObject.drawingObject.type === "roof"
          ) {
            this.fabricObject.x = e.pointer.x;
            this.fabricObject.y = e.pointer.y;
            this.fabricObject.lines[this.fabricObject.lineCounter - 1].set({
              x2: this.fabricObject.x,
              y2: this.fabricObject.y,
            });
            this.fabricObject.fabricObj.renderAll();
          }
        },
        "mouse:dblclick": (e) => {
          if (!this.drawForm.drawing) {
            return;
          }
          this.fabricObject.lines.forEach((item) =>
            this.fabricObject.fabricObj.remove(item)
          );
          this.makeRoof(null);

          this.fabricObject.fabricObj.add(this.fabricObject.roof);
          this.fabricObject.fabricObj.renderAll();

          let monitorArea = {
            monitorAreaId: this.generateUUID(),
            moniPointList: [],
          };
          this.fabricObject.roofPoints.forEach((i) => {
            let percentX = (i.x / this.drawForm.width).toFixed(3);
            let percentY = (i.y / this.drawForm.height).toFixed(3);

            monitorArea.moniPointList.push({
              monitorPointId: monitorArea.moniPointList.length + 1 + "",
              percentX: percentX,
              percentY: percentY,
            });
          });

          this.drawForm.areas.push(monitorArea);

          //clear arrays
          this.fabricObject.roofPoints = [];
          this.fabricObject.lines = [];
          this.fabricObject.lineCounter = 0;
          this.fabricObject.drawingObject.type = "";

          this.drawForm.drawing = false;
        },
      });
    },
    //子页面已标绘的算法canvas图形回显
    getMakeRoof(points, strokeColor, fillColor, data, index, flag) {
      console.log("getMakeRoof points:", points);
      this.clearCanvas();
      const videoItem = $("#videoPlay" + this.index);
      const w = videoItem.width();
      const h = videoItem.height();
      // console.log('%c w=', 'color: red; font-size: 30px', w)
      // console.log('%c h=', 'color: red; font-size: 30px', h)
      points.forEach((a) => {
        let arr = a.moniPointList;
        arr = arr.map((p) => {
          return {
            x: p.percentX * w,
            y: p.percentY * h,
          };
        });
        this.getTipCoordinate(arr, data, index, flag);
        this.fabricObject.fabricObj.add(
          this.makeRoof(arr, strokeColor, fillColor)
        );
      });

      this.fabricObject.fabricObj.renderAll();
    },
    getTipCoordinate(arr, data, index, flag) {
      let xList = arr.map((p) => p.x);
      let xMax = Math.max.apply(null, xList);
      let xMin = Math.min.apply(null, xList);
      this.leftTipCoordinate = Number(
        ((Number(xMax) + Number(xMin)) / 2).toFixed(2)
      );
      let yList = arr.map((p) => p.y);
      let yMax = Math.max.apply(null, yList);
      let yMin = Math.min.apply(null, yList);
      this.topTipCoordinate = Number(
        ((Number(yMax) + Number(yMin)) / 2).toFixed(2)
      );
      // console.log('xList:', xList)
      // console.log('xMax:', xMax)
      // console.log('xMin:', xMin)
      // console.log('this.leftTipCoordinate:', this.leftTipCoordinate)
      // console.log('yList:', yList)
      // console.log('yMax:', yMax)
      // console.log('yMin:', yMin)
      // console.log('this.topTipCoordinate:', this.topTipCoordinate)
      if (flag == "suanfashibie") {
        //提示框
        $("#suanfashibie-tip" + index).show();
        let tipHtml =
          "<div class='tip-box' style='top: " +
          this.topTipCoordinate +
          "px !important;left: " +
          this.leftTipCoordinate +
          "px !important;'>";

        if (data.posType == "2") {
          tipHtml +=
            "<div class='first-tip'>" +
            data.algorithmName +
            "-预置位" +
            "</div>";
          if (data.presetName != null) {
            tipHtml += "<div class='second-tip'>" + data.presetName + "</div>";
          }
        } else {
          tipHtml +=
            "<div class='first-tip'>" + data.algorithmName + "-通道" + "</div>";
        }
        if (!this.isTenant) {
          tipHtml += "<div class='second-tip'>" + data.tenantName + "</div>";
          tipHtml += "<div class='second-tip'>" + data.tenantId + "</div>";
        }
        tipHtml += "</div>";
        $("#suanfashibie-tip" + index).html(tipHtml);
      } else if (flag == "pingbiquyu") {
        //提示框
        $("#pingbiquyu-tip" + index).show();
        let tipHtml =
          "<div class='tip-box' style='top: " +
          this.topTipCoordinate +
          "px !important;left: " +
          this.leftTipCoordinate +
          "px !important;'>";
        tipHtml += "<div class='first-tip'>" + data.areaName + "</div>";
        if (!this.isTenant) {
          tipHtml += "<div class='second-tip'>" + data.tenantName + "</div>";
          tipHtml += "<div class='second-tip'>" + data.tenantId + "</div>";
        }
        tipHtml += "</div>";
        $("#pingbiquyu-tip" + index).html(tipHtml);
      }
      this.tipBoxDeviation(flag, index);
      //$('.aaa').outerWidth()
    },
    tipBoxDeviation(flag, index) {
      let $aa, $bb;
      if (flag == "suanfashibie") {
        $aa = $("#suanfashibie-tip" + index);
        $bb = $("#suanfashibie-tip" + index + " .tip-box");
      } else if (flag == "pingbiquyu") {
        $aa = $("#pingbiquyu-tip" + index);
        $bb = $("#pingbiquyu-tip" + index + " .tip-box");
      }
      let a = $aa.outerWidth();
      let b = $bb.outerWidth();
      let c = $aa.outerHeight();
      let d = $bb.outerHeight();
      let left = a - b - 30;
      let top = 0;
      // if(this.leftTipCoordinate - b / 2 < 0){
      //   left = b/2
      // } else if(this.leftTipCoordinate + b / 2 > a){
      //   left = a - b/2
      // } else{
      //   left = this.leftTipCoordinate
      // }
      // if(this.topTipCoordinate - d /2 < 0 ){
      //   top = d/2
      // } else if(this.topTipCoordinate + d /2 > c ){
      //   top = c - d/2
      // }else{
      //   top = this.topTipCoordinate
      // }

      $bb.css({
        left: left + "px",
        top: top + "px",
        // left:left + 'px',
        // top:top + 'px',
      });
    },
    clearCanvas() {
      if (this.fabricObject.fabricObj) {
        this.fabricObject.fabricObj.clear();
        this.fabricObject.fabricObj.remove(
          this.fabricObject.fabricObj.getActiveObject()
        );
        this.fabricObject.fabricObj.setViewportTransform([1, 0, 0, 1, 0, 0]);
      }
      this.drawForm.areas = [];
    },
    makeRoof(roofPoints, strokeColor, fillColor) {
      let bool = !roofPoints;
      if (bool) {
        roofPoints = this.fabricObject.roofPoints;
      }
      let left = this.findLeftPaddingForRoof(roofPoints);
      let top = this.findTopPaddingForRoof(roofPoints);
      if (bool) {
        let a = {};

        a["x"] = roofPoints[0].x;
        a["y"] = roofPoints[0].y;
        roofPoints.push(a);
      }
      let stroke =
        strokeColor === undefined ? "rgba(74, 144, 226, 1)" : strokeColor;
      let fill =
        fillColor === undefined ? "rgba(255, 163, 37, 0.39)" : fillColor;

      let roof = new fabric.Polyline(roofPoints, {
        fill: fill,
        strokeWidth: 2,
        selectable: false,
        stroke: stroke,
        left: left,
        top: top,
      });

      if (bool) {
        this.fabricObject.roof = roof;
      } else {
        return roof;
      }
    },
    findTopPaddingForRoof(roofPoints) {
      let result = 999999;
      roofPoints.forEach((i) => {
        if (i.y < result) {
          result = i.y;
        }
      });
      return Math.abs(result);
    },
    findLeftPaddingForRoof(roofPoints) {
      var result = 999999;

      roofPoints.forEach((i) => {
        if (i.x < result) {
          result = i.x;
        }
      });
      return Math.abs(result);
    },
    titleSuanFa(data) {
      let posname = data.posType == "1" ? "通道" : "预置位";
      let title = data.algorithmName + "-" + posname;
      return title;
    },
    /**
     * 方法无效
     */
    invalidOp() {
      $message.w("暂不支持");
    },
    /**
     * 是否一行按钮显示不下
     */
    leaveChange() {
      $("#mapSingleVideo" + this.suffix + this.index).removeClass("z-bd-high");
      $("#cloudSingleVideo" + this.index).removeClass("z-bd-cloud-high");
    },
    setTopZindex() {
      this.$emit("click", this.index);
      let zIndex = 0;
      let items = $(".video-item");
      let itemsLength = items.length;
      for (let i = 0; i < itemsLength; i++) {
        let tempZindex = document.defaultView
          .getComputedStyle(items[i], null)
          .getPropertyValue("z-index");
        if (tempZindex > 1) {
          zIndex = zIndex > tempZindex ? zIndex : tempZindex;
        }
      }
      let myZindex = $("#videoDialog" + this.index)
        .parent()
        .css("z-index");
      if (myZindex <= zIndex) {
        $("#videoDialog" + this.index)
          .parent()
          .css("z-index", ++zIndex);
      }
    },
    // 弹窗改变大小
    addDialogResizeEventListener() {
      // 弹窗
      const dialogElement = $("#videoDialogDrag" + this.index)[0];
      if (!dialogElement) {
        return false;
      }
      /* 拖动 */
      const computedStyle = document.defaultView.getComputedStyle(
        dialogElement,
        null
      );
      dialogElement.onmousedown = (mousedownEvent) => {
        // 当前鼠标坐标
        const currentX = mousedownEvent.clientX;
        const currentY = mousedownEvent.clientY;
        let computedStyleLeft, computedStyleTop;
        // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
        if (computedStyle.left.includes("%")) {
          computedStyleLeft =
            +document.body.clientWidth *
            (+computedStyle.left.replace(/\%/g, "") / 100);
          computedStyleTop =
            +document.body.clientHeight *
            (+computedStyle.top.replace(/\%/g, "") / 100);
        } else {
          computedStyleLeft = +computedStyle.left.replace(/\px/g, "");
          computedStyleTop = +computedStyle.top.replace(/\px/g, "");
        }
        document.onmousemove = function (mousemoveEvent) {
          const dialogElementLeft =
            mousemoveEvent.clientX - currentX + computedStyleLeft;
          const dialogElementTop =
            mousemoveEvent.clientY - currentY + computedStyleTop;
          el.style.left = dialogElementLeft + "px";
          el.style.top = dialogElementTop + "px";
        };
        document.onmouseup = function () {
          document.onmousemove = null;
          document.onmouseup = null;
        };
      };
    },
    chooseVideo() {
      if (
        $(".vjs-big-play-button", $("#videoSingleId" + this.index)).is(
          ":visible"
        )
      ) {
        $(".vjs-big-play-button", $("#videoSingleId" + this.index)).click();
        this.screenItem.pause = false;
      }
      this.getControllerInfo();
    },
    mouseDownVideo() {
      // 用于表示在视频区域按下鼠标（无须等待弹起，不是点击事件）的触发，外部使用这个事件做z-index操作等
      this.$emit("clickvideo", this.index);
    },
    /**
     * 摄像机 速度 改变
     */
    cameraApertureSpeedChange(value, oldValue) {
      if (!this.checkPermissions("video:videoControlRole", true)) {
        return false;
      }
      if (value === undefined) {
        this.cameraApertureSpeed = oldValue;
      }
    },
    /**
     * 摄像机 倍数 改变
     */
    cameraApertureMulChange(e, operType, operContent) {
      if (!this.checkPermissions("video:videoControlRole", operContent === 1)) {
        return false;
      }
      if (e) {
        e.preventDefault();
        if (operContent === 1) {
          this.cloudTouch = operType;
        } else {
          this.cloudTouch = false;
        }
      }
      let params = {
        deviceCode: this.deviceCode, //设备编码
        channelCode: this.channelCode, //通道编码
        customerCode: this.loginInfo.tenantId, //租户id
        operType: operType, //聚焦/缩放操作类型
        operContent: operContent, //动作开始/结束 1开始 0结束
        step: this.cameraApertureSpeed, //速度
      };
      let opMsg = operType == "" ? "聚焦" : "缩放";
      doCameraFocusOrZoom(params).then((res) => {
        if (operContent == 0 && res.code != 200) {
          $message.a(res);
        }
        if (operContent == 0 && res.code == 200) {
          this.getCompass(null);
        }
      });
    },
    ready3Dpty(canDraw = !this.screenItem.canDraw, unTs) {
      if (!this.checkPermissions("video:videoControlRole", canDraw)) {
        return false;
      }
      if (!!this.screenItem.canDraw === !!canDraw) {
        return false;
      }
      this.screenItem.canDraw = canDraw;
      this.openTool("ready3Dpty", canDraw);
      if (canDraw) {
        this.screenMessTs("将框选的区域放大，从左往右为放大，从右往左为缩小");
      } else {
        !unTs && this.screenMessTs("3D放大已关闭");
      }
      this.unbindDianzi();
      this.screenItem.focusPoint = false;
    },
    drawMousedown: function (e) {
      if (e.button != 0) {
        return false;
      }
      this.drawArea = true;
      if (this.screenItem.canDraw) {
        this.drawX = e.offsetX; // 鼠标落下时的X
        this.drawY = e.offsetY; // 鼠标落下时的Y
        this.drawXoffset = 0;
        this.drawYoffset = 0;
      }
    },
    drawMouseup: function (e) {
      if (e.button != 0) {
        return false;
      }
      this.drawArea = false;
      if (this.screenItem.canDraw) {
        let canvas = e.target;
        let ctx = canvas.getContext("2d");
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        let parentDivWidth = canvas.parentElement.parentElement.clientWidth;
        let parentDivHeight = canvas.parentElement.parentElement.clientHeight;
        let ptzData = {
          deviceCode: this.deviceCode,
          channelCode: this.channelCode,
          customerCode: this.loginInfo.tenantId, //租户id
          windowWidth: parentDivHeight, //播放窗口宽度像素值
          windowLength: parentDivWidth, //播放窗口长度像素值
          midPointX: parseInt(this.drawXoffset / 2) + this.drawX,
          midPointY: parseInt(this.drawYoffset / 2) + this.drawY,
          lengthX: Math.abs(this.drawXoffset),
          lengthY: Math.abs(this.drawYoffset),
          zoomFlag: this.drawXoffset > 0,
        };
        thirdLocation(ptzData).then((res) => {
          if (res.code != 200) {
            $message.a(res);
          } else {
            setTimeout(() => {
              this.getCompass(null);
              this.getControllerInfo(9);
            }, 500);
          }
        });
      }
    },
    drawMousemove: function (e) {
      if (this.drawArea && this.screenItem.canDraw) {
        this.drawXoffset = e.offsetX - this.drawX;
        this.drawYoffset = e.offsetY - this.drawY;
        const canvas = e.target;
        let parentDivWidth = e.target.parentElement.clientWidth;
        let parentDivHeight = e.target.parentElement.clientHeight;
        canvas.width = parentDivWidth;
        canvas.height = parentDivHeight;
        let ctx = canvas.getContext("2d");
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.beginPath();
        //设置线条颜色，必须放在绘制之前
        ctx.strokeStyle = "#ff4444";
        // 线宽设置，必须放在绘制之前
        ctx.lineWidth = 2;
        ctx.strokeRect(
          this.drawX,
          this.drawY,
          this.drawXoffset,
          this.drawYoffset
        );
      }
    },
    closeOptions() {
      this.$refs["protocalTypeOptions"][0].blur();
    },
    /**
     * 气象数据
     */
    getWeather(weatherShow = !this.screenItem.weatherShow) {
      if (this.btnPowers["video_weather_btn"] !== "1") {
        return false;
      }
      let sources = [
        {
          camera: {
            deviceCode: this.deviceCode,
            channelCode: this.channelCode,
            longitude: this.lng,
            latitude: this.lat,
          },
        },
      ];
      this.$set(this.screenItem, "sources", sources);
      this.$set(this.screenItem, "weatherShow", weatherShow);
      this.openTool("getWeather", weatherShow);
    },
    /**
     * 空气质量
     */
    getAir(airShow = !this.screenItem.airShow) {
      if (this.btnPowers["video_air_btn"] !== "1") {
        return false;
      }
      let sources = [
        {
          camera: {
            deviceCode: this.deviceCode,
            channelCode: this.channelCode,
            longitude: this.lng,
            latitude: this.lat,
          },
        },
      ];
      this.$set(this.screenItem, "sources", sources);
      this.$set(this.screenItem, "airShow", airShow);
      this.openTool("getAir", airShow);
    },
    /**
     * 网格信息
     */
    getGrid(grid = !this.grid) {
      if (!this.isTenant) {
        return false;
      }
      this.grid = grid;
      this.openTool("getGrid", grid);
    },
    /**
     * 监测数据
     */
    getMonitorData(iotShow = !this.screenItem.iotShow) {
      if (!this.isTenant) {
        return false;
      }
      let sources = [
        {
          camera: {
            deviceCode: this.deviceCode,
            channelCode: this.channelCode,
            longitude: this.lng,
            latitude: this.lat,
          },
        },
      ];
      this.$set(this.screenItem, "sources", sources);
      this.$set(this.screenItem, "iotShow", iotShow);
      this.openTool("getMonitorData", iotShow);
    },
    readyFocusPoint(focusPoint = !this.screenItem.focusPoint) {
      if (!this.checkPermissions("video:videoControlRole", focusPoint)) {
        return false;
      }
      if (!!this.screenItem.focusPoint === !!focusPoint) {
        return false;
      }
      this.screenItem.focusPoint = focusPoint;
      this.openTool("readyFocusPoint", focusPoint);
      this.unbindDianzi();
      this.screenItem.canDraw = false;
    },
    /**
     * 语音对讲
     */
    voiceIntercom(isVoiceIntercom = !this.screenItem.isVoiceIntercom) {
      if (!!isVoiceIntercom === !!this.screenItem.isVoiceIntercom) {
        return false;
      }
      if (!isVoiceIntercom) {
        this.closeVoiceIntercom();
        return false;
      }
      let params = {
        reqFrom: 0, // 请求来源 0:pc端  1:app端
        netType: store.getters.netType, // 音频通道的网域类型：1-公网对讲(默认值为1)；0-局域内网对讲；
        protocolType: String(store.getters.netType) === "0" ? 5 : 9, //协议类型: 5-ws； 6-铁塔私协；
        deviceCode: this.deviceCode, // 设备编码
        channelCode: this.channelCode, // 通道编码
        deviceType: this.all.deviceType || "",
      };
      getAudioChannel(params).then((res) => {
        if (res.code === 200) {
          this.$set(this.screenItem, "isVoiceIntercom", true);
          this.getAudio(res.data.streamUrl);
          $message.s("对讲已打开");
        } else {
          $message.a(res);
          this.closeVoiceIntercom();
        }
      });
    },
    /**
     * 语音对讲 开启
     */
    getAudio(url) {
      try {
        this.$emit("intercomBack", 1);
        Recorder.start(url, this.errorFunCell, undefined, () => {
          this.closeVoiceIntercom();
        }).catch((error) => {
          this.errorFunCell(error.message);
        });
      } catch (e) {
        this.errorFunCell("推流失败:" + e);
      }
    },
    /**
     * 语音对讲 异常
     */
    errorFunCell(errorTitle) {
      this.closeVoiceIntercom();
      $message.error(errorTitle);
    },
    /**
     * 语音对讲 关闭
     */
    closeVoiceIntercom() {
      this.$emit("intercomBack", 2);
      Recorder.stop();
      this.$set(this.screenItem, "isVoiceIntercom", false);
    },

    // 看这里鼠标移动
    focusMousemove(e) {
      if (this.screenItem.focusPoint) {
        let thisTransform = this.myTransform;
        if (this.fullScreenFlag) {
          thisTransform = 1;
        }
        const eLeft =
          (e.clientX - e.currentTarget.getBoundingClientRect().left - 17) /
          thisTransform;
        const eTop =
          (e.clientY - e.currentTarget.getBoundingClientRect().top - 17) /
          thisTransform;
        document.getElementById("focus-big" + this.index).style.left =
          eLeft + "px";
        document.getElementById("focus-big" + this.index).style.top =
          eTop + "px";
      }
    },
    doFocus(e) {
      if (e.button != 0 || !this.screenItem.focusPoint) {
        return false;
      }
      let divWidth = e.currentTarget.clientWidth;
      let divHeight = e.currentTarget.clientHeight;
      let thisTransform = this.myTransform;
      if (this.fullScreenFlag) {
        thisTransform = 1;
      }
      const eLeft =
        (e.clientX - e.currentTarget.getBoundingClientRect().left) /
        thisTransform;
      const eTop =
        (e.clientY - e.currentTarget.getBoundingClientRect().top) /
        thisTransform;
      let ptzData = {
        deviceCode: this.deviceCode,
        channelCode: this.channelCode,
        customerCode: this.loginInfo.tenantId, //租户id
        windowWidth: divHeight, //播放窗口宽度像素值
        windowLength: divWidth, //播放窗口长度像素值
        midPointX: parseInt(eLeft),
        midPointY: parseInt(eTop),
        lengthX: 0,
        lengthY: 0,
        zoomFlag: true,
      };
      thirdLocation(ptzData).then((res) => {
        if (res.code != 200) {
          $message.a(res);
        } else {
          setTimeout(() => {
            this.getCompass(null);
            this.getControllerInfo(9);
          }, 500);
        }
      });
    },
    getCompass(compass = !this.screenItem.compass) {
      const checkOpen = compass === null;
      if (!checkOpen) {
        this.screenItem.compass = this.compass = compass;
        this.openTool("getCompass", compass);
      }
      if (!this.screenItem.compass) {
        return false;
      }
      const params = {
        deviceCode: this.deviceCode,
        channelCode: this.channelCode,
      };
      let _this = this;
      this.compass = false;
      getCompass(params).then((res) => {
        if (res.code == 200) {
          if (res.data.pan > 360 || res.data.pan < -360) {
            res.data.pan = "--";
            res.data.tilt = "--";
            res.data.zoom = "--";
            res.data.viewableAngle = "--";
            $message.e("pan参数异常");
            this.getCompass(false);
            return false;
          } else if (res.data.pan < 0) {
            res.data.pan = 360 + res.data.pan;
          }
          this.compass = res.data;
          $("#map-t" + _this.index).css(
            "transform",
            "translate(-50%,-50%) rotate(" +
              (180 - res.data.viewableAngle) +
              "deg)"
          );
          $("#map-z" + _this.index).css(
            "transform",
            "translate(-50%,-50%) rotate(" +
              (-(180 - res.data.viewableAngle) / 2 + _this.compass.pan) +
              "deg)"
          );
        } else {
          $message.a(res);
          this.getCompass(false);
        }
      });
    },
    /**
     * 离开页面暂停的视频返回时继续播放
     */
    videoGotoPlay(type) {
      if (this.screenItem.source) {
        if (type) {
          if (this.screenItem.pause) {
            $("#videoSingleId" + this.index)
              .find(".vjs-play-control.vjs-paused, .video-tools .icon-bofang")
              .click();
            this.screenItem.pause = false;
          }
        } else {
          if (!this.screenItem.pause) {
            $("#videoSingleId" + this.index)
              .find(".vjs-play-control.vjs-playing, .video-tools .icon-zanting")
              .click();
            this.screenItem.pause = true;
          }
        }
      }
    },
    dianziRate(dianzi = !this.screenItem.dianzi) {
      this.screenItem.dianzi = dianzi;
      this.openTool("dianziRate", dianzi);
      let choosedWin = this.screenItem;
      let _this = this;
      if (!this.screenItem.dianzi) {
        this.unbindDianzi();
        return false;
      }
      this.screenItem.canDraw = false;
      this.screenItem.focusPoint = false;
      choosedWin.rateNum = 1;
      choosedWin.oldLeft = 0;
      choosedWin.oldTop = 0;
      choosedWin.moveFlag = false;
      choosedWin.downX = 0;
      choosedWin.downY = 0;
      choosedWin.moveXoffset = 0;
      choosedWin.moveYoffset = 0;
      $("#videoSingleId" + _this.index).on("wheel", function (e) {
        e.stopPropagation();
        // true 放大 false 缩小
        let deltay = e.originalEvent.deltaY < 0;
        let originRateNum = choosedWin.rateNum;
        choosedWin.rateNum = choosedWin.rateNum * (deltay ? 1.2 : 0.8);
        choosedWin.rateNum =
          choosedWin.rateNum < 1 ? 1 : choosedWin.rateNum.toFixed(2);
        let width = $("#videoSingleId" + _this.index).width();
        let height = $("#videoSingleId" + _this.index).height();
        let left = e.originalEvent.layerX - choosedWin.oldLeft;
        let top = e.originalEvent.layerY - choosedWin.oldTop;
        let transLeft = _this.getTransValue(
          left,
          choosedWin.oldLeft,
          choosedWin.rateNum,
          originRateNum,
          width
        );
        let transTop = _this.getTransValue(
          top,
          choosedWin.oldTop,
          choosedWin.rateNum,
          originRateNum,
          height
        );
        choosedWin.oldLeft = transLeft;
        choosedWin.oldTop = transTop;
        $(".video-player", $("#videoSingleId" + _this.index))
          .eq(0)
          .css({
            transform: "scale(" + choosedWin.rateNum + ")",
            "transform-origin": "0px  0px",
            left: transLeft + "px",
            top: transTop + "px",
          });
        $(".point-div", $("#videoSingleId" + _this.index)).css({
          left: -transLeft / choosedWin.rateNum + "px",
          top: -transTop / choosedWin.rateNum + "px",
          width: width / choosedWin.rateNum,
          height: height / choosedWin.rateNum,
        });
      });
      $("#videoSingleId" + _this.index).on("mousedown", function (e) {
        if (e.button != 0) {
          return false;
        }
        e.stopPropagation();
        choosedWin.moveFlag = true;
        choosedWin.downX = e.screenX;
        choosedWin.downY = e.screenY;
      });
      $("#videoSingleId" + _this.index).on("mousemove", function (e) {
        if (!choosedWin.moveFlag) {
          return false;
        }
        e.stopPropagation();
        choosedWin.moveXoffset = e.screenX - choosedWin.downX;
        choosedWin.moveYoffset = e.screenY - choosedWin.downY;
        let width = $("#videoSingleId" + _this.index).width();
        let height = $("#videoSingleId" + _this.index).height();
        let maxMoveX = width * (choosedWin.rateNum - 1);
        let maxMoveY = height * (choosedWin.rateNum - 1);
        if (choosedWin.oldLeft + choosedWin.moveXoffset > 0) {
          choosedWin.moveXoffset = -choosedWin.oldLeft;
        }
        if (choosedWin.oldTop + choosedWin.moveYoffset > 0) {
          choosedWin.moveYoffset = -choosedWin.oldTop;
        }
        if (choosedWin.oldLeft + choosedWin.moveXoffset < -maxMoveX) {
          choosedWin.moveXoffset = -maxMoveX - choosedWin.oldLeft;
        }
        if (choosedWin.oldTop + choosedWin.moveYoffset < -maxMoveY) {
          choosedWin.moveYoffset = -maxMoveY - choosedWin.oldTop;
        }
        $(".video-player", $("#videoSingleId" + _this.index))
          .eq(0)
          .css({
            left: choosedWin.oldLeft + choosedWin.moveXoffset + "px",
            top: choosedWin.oldTop + choosedWin.moveYoffset + "px",
          });
        $(".point-div", $("#videoSingleId" + _this.index)).css({
          left:
            -(choosedWin.oldLeft + choosedWin.moveXoffset) /
              choosedWin.rateNum +
            "px",
          top:
            -(choosedWin.oldTop + choosedWin.moveYoffset) / choosedWin.rateNum +
            "px",
        });
      });
      $(document).on("mouseup", function (e) {
        if (e.button != 0 || !choosedWin.dianzi) {
          return false;
        }
        e.stopPropagation();
        choosedWin.moveFlag = false;
        choosedWin.oldLeft = choosedWin.oldLeft + choosedWin.moveXoffset;
        choosedWin.oldTop = choosedWin.oldTop + choosedWin.moveYoffset;
        choosedWin.moveXoffset = 0;
        choosedWin.moveYoffset = 0;
      });
      this.$forceUpdate();
    },
    unbindDianzi() {
      this.screenItem.dianzi = false;
      let choosedWin = this.screenItem;
      $("#videoSingleId" + this.index)
        .off("wheel")
        .off("mousedown")
        .off("mousemove")
        .off("mouseup");
      choosedWin.rateNum = 1;
      choosedWin.oldLeft = 0;
      choosedWin.oldTop = 0;
      choosedWin.moveFlag = false;
      choosedWin.downX = 0;
      choosedWin.downY = 0;
      choosedWin.moveXoffset = 0;
      choosedWin.moveYoffset = 0;
      $(".video-player", $("#videoSingleId" + this.index))
        .eq(0)
        .css({
          transform: "scale(" + choosedWin.rateNum + ")",
          "transform-origin": "0 0",
          left: "0px",
          top: "0px",
        });
      this.$forceUpdate();
    },
    /**
     * 计算电子放大偏移量
     * @param leftTop
     * @param oldLeftTop
     * @param nextRate
     * @param oldRate
     * @param widthHeight
     * @returns {*}
     */
    getTransValue(leftTop, oldLeftTop, nextRate, oldRate, widthHeight) {
      let maxResult = widthHeight * (nextRate - 1);
      let result = (1 - nextRate / oldRate) * leftTop + oldLeftTop;
      if (result > 0) {
        result = 0;
      }
      if (-result > maxResult) {
        result = -maxResult;
      }
      return result;
    },
    screenMessTs(text) {
      this.$refs["ts"].doMessTs(text, true);
    },
    /**
     * 生成uuid
     */
    getUUID() {
      const crypto = window.crypto || window.msCrypto;
      const array = new Uint32Array(1);
      const r = crypto.getRandomValues(array)[0];
      return Date.now() + "999" + r;
    },
    /**
     * 校验是否全屏
     */
    checkScreenFull() {
      const a =
        document.mozFullScreen ||
        document.fullScreen ||
        document.webkitIsFullScreen;
      const b =
        document.webkitRequestFullScreen ||
        document.mozRequestFullScreen ||
        document.msFullscreenEnabled;
      this.isScreenFull = a || b;
    },
    /**
     * 校验权限
     */
    checkPermissions(value, ts) {
      const all = "*:*:*";
      const permissions = this.permissions || [];
      const b = permissions.includes(all) || permissions.includes(value);
      if (!b && ts) {
        if (value === "video:videoControlRole") {
          $message.w("您没有云台控制权限，请联系管理员。");
        } else if (value === "video:videoPreset") {
          $message.w("您没有预置位控制权限，请联系管理员。");
        } else if (value === "video:videoCruisePlan") {
          $message.w("您没有巡航控制权限，请联系管理员。");
        } else {
          $message.w("您暂无权限，如需获取权限，请联系管理员。");
        }
      }
      return b;
    },
  },
};
</script>

<style lang="scss" scoped>
@import "../../../assets/styles/video-base.scss";
@import "../../../assets/styles/video-ly.scss";
.video-player {
  /deep/ .vjs-big-play-button {
    display: none !important;
  }
}
.video-play .play-item.playing .choose-style {
  .close {
    position: absolute;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.4);
    display: none;
    align-items: center;
    justify-content: center;
    line-height: 1;
    top: 12px;
    right: 12px;
    z-index: 10000;
    &:before {
      content: "\eacc";
      font-family: iconfont;
      color: #fff;
      font-size: 22px;
      font-weight: bold;
      line-height: 1;
    }
    &:hover {
      opacity: 0.6;
    }
    &:active {
      opacity: 0.8;
    }
  }
  &:hover {
    .close {
      display: flex;
    }
  }
  .record-time {
    position: absolute;
    top: 12px;
    left: 12px;
    height: 32px;
    line-height: 32px;
    padding: 0 12px;
    background: rgba(0, 0, 0, 0.7);
    color: #ffffff;
    font-size: 14px;
    border-radius: 4px;
    pointer-events: none;
  }
  .z-bd-cloud {
    overflow: visible !important;
    padding-bottom: 44px;
    bottom: var(--map-for-video-height, 0px);
    .cloud-lock {
      position: absolute;
      bottom: calc(100% + 6px);
      right: 12px;
      height: 32px;
      line-height: 32px;
      background: rgba(0, 0, 0, 0.4);
      border-radius: 8px;
      display: flex;
      justify-content: center;
      align-items: center;
      color: #fff;
      cursor: default;
      min-width: 70px;
      i {
        flex: 1;
        font-size: 14px;
        cursor: pointer;
        border-left: 1px dotted rgba(255, 255, 255, 0.2);
        text-align: center;
        min-width: 32px;
        &:first-child {
          border: 0;
        }
      }
      .optioning {
        font-size: 16px;
      }
      .time {
        margin: 0 12px;
        white-space: nowrap;
      }
      &:hover {
        background: rgba(0, 0, 0, 0.6);
      }
    }
    .inner-control-bt,
    .inner-control-rbt,
    .cruise-pause {
      position: absolute;
      margin: 0 !important;
      bottom: 12px;
      right: 12px;
      border-radius: 8px !important;
      height: 32px !important;
      line-height: 32px !important;
    }
    .inner-control-bt {
      width: 70px !important;
      div:first-child {
        border-right: 1px dotted rgba(255, 255, 255, 0.2) !important;
      }
    }
    .inner-control-rbt {
      width: 65px !important;
      right: 88px;
      padding: 0 12px !important;
      /deep/ .el-input-number {
        transform: none !important;
        padding: 0 !important;
        line-height: 32px !important;
        .el-input__inner {
          padding: 0 !important;
          text-align: left !important;
          font-size: 14px !important;
          color: #fff;
        }
        .el-input-number__decrease,
        .el-input-number__increase {
          overflow: hidden;
          color: #fff;
          &:hover {
            opacity: 0.6;
          }
          &:active {
            opacity: 0.8;
          }
          &.is-disabled {
            opacity: 0.4;
          }
        }
        .el-icon-arrow-up {
          font-size: 14px;
          transform: translateY(3px);
          line-height: 1;
          color: #fff !important;
          &:before {
            content: "\E78F";
          }
        }
        .el-icon-arrow-down {
          font-size: 14px;
          transform: translateY(-3px);
          line-height: 1;
          color: #fff !important;
          &:before {
            content: "\E790";
          }
        }
      }
    }
    .cruise-pause {
      right: 159px;
      background: rgba(0, 0, 0, 0.4);
      padding: 0 12px;
      display: flex;
      align-items: center;
      color: rgba(255, 255, 255, 1);
      word-break: keep-all;
      white-space: nowrap;
      cursor: default;
      .cruise-pause-label {
        font-size: 14px;
        line-height: 1;
      }
      .cruise-pause-icon {
        font-size: 16px;
        line-height: 1;
        cursor: pointer;
        margin-left: 6px;
      }
      .cruise-pause-time {
        font-size: 14px;
        line-height: 1;
        margin-left: 6px;
      }
      &:hover {
        background: rgba(0, 0, 0, 0.6);
      }
    }
  }
  .z-bd-cloud.cloud-for-videomap {
    position: absolute !important;
    top: 86px !important;
    right: 0 !important;
    left: auto !important;
    bottom: auto !important;
    transform-origin: 100% 0;
  }
  &.video-and-map-main-video {
    /deep/ .video-to-map {
      width: 100% !important;
      height: 100% !important;
      max-width: 100% !important;
      max-height: 100% !important;
    }
    &.is-screen-full /deep/ .video-to-map {
      .preset {
        transform: scale(1.5);
        transform-origin: 0 0;
      }
      .v-btns {
        transform: scale(1.5);
        transform-origin: 0 0;
        left: 340px;
      }
    }
    /deep/ .map-box-video {
      z-index: 30;
    }
    &:not(.is-screen-full) /deep/ .map-box-video {
      .top-btn {
        transform: scale(0.78);
        transform-origin: 0 0;
        left: 9px;
        top: 9px;
      }
    }
    &.video-and-map-has-quicktool {
      /deep/ .map-box-video,
      .z-bd-cloud.cloud-for-videomap {
        right: 84px !important;
      }
      &.video-and-map-has-quicktool-common {
        /deep/ .map-box-video,
        .z-bd-cloud.cloud-for-videomap {
          right: 428px !important;
        }
      }
    }
  }
  &.video-and-map-main-map {
    /deep/ .video-to-map {
      z-index: 30;
    }
    &:not(.is-screen-full) /deep/ .video-to-map {
      .preset {
        transform: scale(0.78);
        transform-origin: 0 0;
        left: 9px;
        top: 9px;
        width: 120px;
        max-height: 192px;
      }
      .v-btns {
        transform: scale(0.78);
        transform-origin: 0 0;
        left: 106px;
        top: 9px;
      }
    }
    /deep/ .map-box-video {
      width: 100% !important;
      height: 100% !important;
      max-width: 100% !important;
      max-height: 100% !important;
      .right-btn {
        bottom: 16px;
        left: 16px;
        right: auto;
      }
    }
    &.is-screen-full /deep/ .map-box-video {
      .top-btn {
        transform: scale(1.5);
        transform-origin: 0 0;
      }
      .right-btn {
        transform: scale(1.5);
        transform-origin: 0 100%;
      }
    }
    .video-player {
      width: 38%;
      height: 38%;
      position: absolute;
      right: 0;
      bottom: 0;
      left: auto !important;
      top: auto !important;
      z-index: 29;
      &.large {
        width: 50%;
        height: 50%;
      }
    }
    .cloud-for-videomap {
      display: none !important;
    }
    &.video-and-map-has-quicktool {
      /deep/ .video-to-map,
      .video-player {
        right: 84px;
      }
      &.video-and-map-has-quicktool-common {
        /deep/ .video-to-map,
        .video-player {
          right: 428px;
        }
      }
    }
  }
  &:hover {
    .z-bd-cloud {
      bottom: calc(
        var(--player-toolbar-height, 40px) + var(--map-for-video-height, 0px)
      );
    }
  }
  .suanfashibie-select {
    .suanfashibie-select-box {
      height: 32px;
      line-height: 30px;
      background: rgba(0, 0, 0, 0.7) !important;
      border-radius: 4px;
      border: 1px solid rgba(255, 255, 255, 0) !important;
      color: #ffffff !important;
      font-size: 14px;
      display: flex;
      align-items: center;
      min-width: 160px;
      .suanfashibie-text {
        color: inherit !important;
        padding: 0 12px;
      }
      .suanfashibie-icon {
        height: 100%;
        line-height: inherit;
        display: flex;
        align-items: center;
        .icon-class {
          color: #fff !important;
          line-height: 1;
          font-size: 18px;
          &:before {
            content: "\E87D";
          }
          &.icon-nav-top {
            transform: rotate(180deg);
          }
        }
      }
      &:after {
        display: none;
      }
    }
    .suanfashibie-select-options {
      top: 54px;
      background: rgba(0, 0, 0, 0.7) !important;
      border-radius: 4px !important;
      border: 0 !important;
      max-height: calc(100% - 62px - var(--player-toolbar-height, 40px));
      min-width: 160px;
      .options-box-padding {
        border: 0 !important;
        padding: 12px;
        position: relative;
        &:hover,
        &.active {
          background: rgba(255, 255, 255, 0.2);
        }
        &:after {
          content: "";
          width: calc(100% - 24px);
          height: 1px;
          background: rgba(232, 243, 254, 0.2);
          position: absolute;
          left: 12px;
          bottom: 0;
          margin: 0;
        }
        &:last-child:after {
          display: none;
        }
      }
      .options-box {
        .options-text {
          flex: 1;
          opacity: 1;
          color: #ffffff !important;
          width: auto;
        }
        .options-icon {
          align-items: center;
          height: auto;
          width: auto;
          .icon-class {
            font-size: 20px;
            color: #ffffff !important;
            margin-left: 6px;
            line-height: 1;
          }
        }
      }
      .options-presetName-class {
        opacity: 1 !important;
        font-size: 12px;
        margin-top: 6px;
        color: #fff !important;
      }
      .empty-box {
        background: none !important;
        border-radius: 4px;
        border: 0;
        color: rgba(255, 255, 255, 0.7) !important;
        opacity: 1 !important;
        padding: 12px;
      }
    }
    .canvas-div {
      display: none;
      pointer-events: none;
    }
  }
  .compass-div {
    div .map-t {
      background: #fff;
    }
  }
}
.no-playback {
  position: absolute;
  left: 50%;
  top: 70%;
  transform: translateX(-50%);
  pointer-events: none;
  font-size: 16px;
  white-space: nowrap;
}
.video-dialog {
  border-radius: 10px;
  &.full {
    width: 100vw !important;
    height: 100vh !important;
    position: fixed !important;
    left: 0 !important;
    top: 0 !important;
    z-index: 2000 !important;
    transform: none !important;
  }
  &.border:after {
    content: "";
    width: 100%;
    height: 100%;
    position: absolute;
    left: 0;
    top: 0;
    z-index: 2;
    border-radius: inherit;
    border: 2px solid var(--border);
    pointer-events: none;
  }
  &.ar-border {
    .video-right {
      .extend-1,
      .extend-2 {
        position: absolute;
        width: 100%;
        height: 100%;
        border-radius: inherit;
        top: 0;
        left: 0;
        z-index: 99;
        pointer-events: none;
        &:before,
        &:after {
          content: "";
          width: 30px;
          height: 30px;
          position: absolute;
        }
      }
      .extend-1 {
        &:before {
          border-top: 4px solid var(--ar-border);
          border-left: 4px solid var(--ar-border);
          border-radius: 10px 0 0 0;
          top: -2px;
          left: -2px;
        }
        &:after {
          border-top: 4px solid var(--ar-border);
          border-right: 4px solid var(--ar-border);
          border-radius: 0 10px 0 0;
          top: -2px;
          right: -2px;
        }
      }
      .extend-2 {
        &:before {
          border-bottom: 4px solid var(--ar-border);
          border-left: 4px solid var(--ar-border);
          border-radius: 0 0 0 10px;
          bottom: -2px;
          left: -2px;
        }
        &:after {
          border-bottom: 4px solid var(--ar-border);
          border-right: 4px solid var(--ar-border);
          border-radius: 0 0 10px 0;
          bottom: -2px;
          right: -2px;
        }
      }
      .video-real {
        border: 2px solid var(--ar-border);
        border-radius: 6px;
      }
    }
  }
  &.checked:after {
    content: "";
    width: 100%;
    height: 100%;
    position: absolute;
    left: 0;
    top: 0;
    z-index: 2;
    border-radius: inherit;
    border: 2px solid var(--checkedBorder);
    pointer-events: none;
  }
  &.moving {
    .video-dialog-bg {
      pointer-events: none;
    }
  }
  &.hide {
    width: 0 !important;
    .tuoZhuai,
    .video-right {
      display: none;
    }
  }
  &.full-screen {
    .video-real {
      border-radius: 0;
    }
  }
  .video-real {
    position: relative;
  }
  .video-tiitle {
    width: 100%;
    height: 30px;
    line-height: 30px;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 88;
    display: flex;
    align-items: center;
    color: #deebff;
    font-size: 12px;
    background: linear-gradient(90deg, #172537, rgba(0, 0, 0, 0.01));
    padding: 0 10px;
    .video-status {
      font-size: 12px;
      margin: 0 6px 0 2px;
      line-height: 1;
      position: relative;
      top: 1px;
      &:after {
        content: "\E8A5";
        font-family: iconfont;
        width: 28px;
        height: 28px;
        line-height: 28px;
        text-align: center;
        border-radius: 50%;
        background: #1dbe8a;
        color: #fff;
        font-size: 14px;
        padding: 1px 2px 0 0;
        position: absolute;
        z-index: 2;
        left: -4px;
        bottom: -2px;
        transform: scale(0.45);
        transform-origin: 0 100%;
      }
      &.off-line:after {
        content: "\E8A4";
        background: #eb5257;
        padding: 1px 0 0 0;
      }
      &.on-playing:after {
        content: "\E8A8";
        background: #1dbe8a;
        font-size: 12px;
        padding: 0;
      }
      &.on-pauseing:after {
        content: "\e8ac";
        background: #1dbe8a;
        font-size: 12px;
        padding: 0;
      }
    }
    .video-name {
      flex: 1;
      display: block;
      word-break: keep-all;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    .video-time {
      margin-left: 12px;
    }
  }
}

.full-big {
  transform: scale(2);

  &.big-left-top {
    transform-origin: 0 0;
  }

  &.big-left-bottom {
    transform-origin: 0 100%;
  }

  &.big-right-top {
    transform-origin: 100% 0;
  }

  &.big-right-bottom {
    transform-origin: 100% 100%;
  }
}
</style>
<style lang="scss">
.protocol-option-ly.el-popper {
  background-color: #666666 !important;
  border: 1px solid #9a9a9a !important;
}

.protocol-option-ly .el-select-dropdown__item:hover,
.protocol-option-ly .el-select-dropdown__item.hover {
  background: #9a9a9a !important;
}

.protocol-option-ly.el-popper[x-placement^="top"] .popper__arrow:after {
  border-top-color: #666666 !important;
}

.protocol-option-ly.el-popper[x-placement^="bottom"] .popper__arrow:after {
  border-bottom-color: #666666 !important;
}
.easy-player-fill-container .video-js {
  background-color: #090f17;
}

.cascader-popper-cs.el-cascader__dropdown {
  background: #083350 !important;
  border-color: #0472b2 !important;
}

.cascader-popper-cs.el-cascader__dropdown .el-cascader__dropdown__item {
  color: #fff !important;
}

.cascader-popper-cs.el-cascader__dropdown
  .el-cascader__dropdown__item.selected {
  background: rgb(0, 101, 160) !important;
}

.cascader-popper-cs.el-cascader__dropdown .el-cascader__dropdown__item.hover,
.cascader-popper-cs.el-cascader__dropdown .el-cascader__dropdown__item:hover {
  background: rgba(0, 101, 160, 0.5) !important;
}

.cascader-popper-cs.el-cascader__dropdown .popper__arrow {
  border-bottom-color: #0472b2 !important;
  border-top-color: #0472b2 !important;
}

.cascader-popper-cs.el-cascader__dropdown .popper__arrow:after {
  border-bottom-color: rgba(1, 83, 126, 0.32) !important;
  border-top-color: rgba(1, 83, 126, 0.32) !important;
}

.cascader-popper-cs.el-cascader__dropdown .el-scrollbar__wrap {
  overflow: auto;
}

.cascader-popper-cs .el-cascader-node.in-active-path {
  color: #ffffff;
}

.cascader-popper-cs .el-cascader-menu {
  color: #cccccc;
}

.cascader-popper-cs .el-cascader-node:focus,
.cascader-popper-cs .el-cascader-node:hover {
  background: rgba(0, 101, 160, 0.5);
  color: #ffffff;
}

.video-datetime input,
.video-datetime button,
.video-datetime .el-picker-panel__footer {
  background: none;
  color: #fff;
}

.video-datetime .el-date-picker__header-label {
  color: #dddddd;
}

.video-datetime .el-date-picker__header-label:hover {
  color: #ffffff;
}

.cascader-cs {
  margin-left: 20px;

  input.el-input__inner {
    height: 30px;
    line-height: 30px;
    border-color: #0472b2;
    outline: none;
    border-radius: 3px;
    background: rgba(1, 83, 126, 0.32);
    color: #fff;
  }

  .el-input__icon {
    color: #0472b2;
  }

  .el-input--mini.el-input--suffix {
    width: calc(100% - 30px) !important;
  }

  .el-cascader--mini {
    line-height: 30px;
  }
}

.video-datetime.el-picker-panel {
  color: #ffffff;
  background: #083350 !important;
  border: none;
  border-radius: 10px;
  box-shadow: 0 3px 10px 4px rgba(0, 0, 0, 0.09), 0 2px 4px 0 rgba(0, 0, 0, 0.1);
  backdrop-filter: blur(8px);
  transform: translateZ(0);

  .el-input input::-webkit-input-placeholder {
    color: #d2ffef;
  }

  .el-input input::-moz-placeholder {
    color: #d2ffef;
  }

  .el-input input::-ms-input-placeholder {
    color: #d2ffef;
  }
}

.video-datetime.el-picker-panel:after {
  content: "";
  width: 100%;
  height: 100%;
  position: absolute;
  left: 0;
  top: 0;
  background: hsla(0, 0%, 50.6%, 0.2);
  backdrop-filter: blur(8px);
  transform: translateZ(0);
  border-radius: inherit;
  z-index: -1;
}

.video-datetime.el-picker-panel .el-date-range-picker .el-popper {
  color: #ffffff;
  background: #083350 !important;
  border: none;
  border-radius: 10px;
  box-shadow: 0 3px 10px 4px rgba(0, 0, 0, 0.09), 0 2px 4px 0 rgba(0, 0, 0, 0.1);
  backdrop-filter: blur(8px);
  transform: translateZ(0);
}

.c-video-select .el-picker-panel__icon-btn {
  color: #fff;
}

.c-video-select .el-date-table th {
  color: #fff;
  padding: 0;
}

.c-video-select .el-date-table td.today span {
  color: #00a8ff;
  font-weight: 700;
}

.c-video-select .el-date-table td.in-range div {
  background-color: rgba(255, 255, 255, 0.2);
}

.c-video-select .el-date-table td.end-date span,
.c-video-select .el-date-table td.start-date span {
  background: #00a8ff;
}

.c-video-select .el-date-table td.end-date div,
.c-video-select .el-date-table td.start-date div {
  color: #fff;
}

.c-video-select .el-date-table td.in-range div,
.c-video-select .el-date-table td.in-range div:hover,
.c-video-select .el-date-table.is-week-mode .el-date-table__row.current div,
.c-video-select .el-date-table.is-week-mode .el-date-table__row:hover div {
  background-color: rgba(255, 255, 255, 0.2);
}

.c-video-select .el-date-table td.disabled div {
  background-color: rgba(255, 255, 255, 0.2);
  opacity: 1;
  cursor: not-allowed;
  color: #c0c4cc;
}

.c-video-select .el-date-table td.current:not(.disabled) span {
  color: #fff;
  background-color: #0472b2;
}

.c-video-select .el-date-table td.available:hover {
  background-color: rgba(255, 255, 255, 0.2);
  color: #00a8ff;
}

.c-video-select .el-slider__button {
  border: 2px solid #083350;
  background-color: #fff;
}

.tuoZhuai {
  width: 10px !important;
  height: 10px !important;
  overflow: hidden;
  position: absolute;
  right: 0;
  bottom: 0;
  z-index: 101;
  transform: scale(1.5);
  transform-origin: 100% 100%;
}
.tuoZhuai:hover {
  cursor: se-resize;
}
.miniBar {
  .play-opt-btns2 i {
    margin-left: 0px !important;
  }
}
.ar-l2 {
  .easy-player-fill-container .video-js {
    background-color: #000e0b;
  }
}
.ar-g {
  .video-play .play-item.playing .choose-style {
    background: #15130c !important;
  }
}
</style>
